Unity Convert Texture to Texture2d takes a lot of time in android device

Viewed 4380

I have a function that converting a RGB565 Texture2d to a RGB24Texture2d.

I use Texture2d.ReadPixs() api and it was successfully achieved but when it's running on android It will take 50 milliseconds on Texture2d.ReadPixs() and the readed size is just 640*480.

I find a solution here (to use glReadPixels) but when the so file was compiled from Android Studio it did not work on unity. I am not good at c++ and Android Studio...

Is there any other solution to fix it?

Thank you in advance!

 public static void textureToTexture2D(Texture texture, Texture2D texture2D)
 {
     if (texture == null)
         throw new ArgumentNullException("texture == null");
     if (texture2D == null)
         throw new ArgumentNullException("texture2D == null");
     if (texture.width != texture2D.width || texture.height != texture2D.height)
         throw new ArgumentException("texture and texture2D need to be the same size.");
     RenderTexture prevRT = RenderTexture.active;
     if (texture is RenderTexture)
     {
         RenderTexture.active = (RenderTexture)texture;
         
         texture2D.ReadPixels(new UnityEngine.Rect(0f, 0f, texture.width, texture.height), 0, 0, false);
         texture2D.Apply(false, false);
     }
     else
     {
         RenderTexture tempRT = RenderTexture.GetTemporary(texture.width, texture.height, 0, RenderTextureFormat.ARGB32);
         Graphics.Blit(texture, tempRT);
         RenderTexture.active = tempRT;
        //it takes the most time on the function about 50ms
         texture2D.ReadPixels(new UnityEngine.Rect(0f, 0f, texture.width, texture.height), 0, 0, false);
         texture2D.Apply(false, false);
         RenderTexture.ReleaseTemporary(tempRT);
     }
     RenderTexture.active = prevRT;
 }
2 Answers

You could also try using Graphics.CopyTexture

public Texture2D toTexture2D(RenderTexture rTex)
{
    Texture2D dest = new Texture2D(rTex.width, rTex.height, TextureFormat.RGBA32, false);

    Graphics.CopyTexture(renderTexture, dest);

    return dest;
}

Texture formats should be compatible (for example, TextureFormat.ARGB32 and RenderTextureFormat.ARGB32 are compatible).

You will need to check though if this is supported on your target device.

Some platforms might not have functionality of all sorts of texture copying (e.g. copy from a render texture into a regular texture). See CopyTextureSupport, and use SystemInfo.copyTextureSupport to check.

Why not trying something simple first:

Texture2D rgb565 = LoadMyTextureOrSomething();
Texture2D rgb24 = new Texture2D(
    width:          rgb565.width ,
    height:         rgb565.height ,
    textureFormat:  TextureFormat.RGB24 ,
    mipChain:       rgb565.mipmapCount!=1
);
rgb24.SetPixels( rgb565.GetPixels() );
rgb24.Apply();// sends changed texture to gpu

Some of this work can be done on worker thread (color conversion part), but requires manual byte[] or NativeArray<byte> processing.

Related