Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Texture2D.LoadImage png... can we load directly to RGBA32 and not ARGB32?

Discussion in 'Scripting' started by cpuRunningHot, Jun 3, 2020.

  1. cpuRunningHot

    cpuRunningHot

    Joined:
    May 5, 2018
    Posts:
    94
    I am loading PNG files for image processing and using Texture2D.GetRawTextureData<Color32> to read/write the pixels efficiently. Working on many 4K maps and have identified this as the faster way of editing them.

    That's great, except I ran into an issue when loading PNG files... they load as ARGB32 by default, and GetRawTextureData<Color32> has the color channels out of order due to the different format.

    I can convert the texture immediately after loading it like this...

    Code (CSharp):
    1.                    
    2. tex.LoadImage(File.ReadAllBytes(fullPath));
    3.  
    4. if (tex.format != TextureFormat.RGBA32)
    5. {
    6.     var convertedTex = new Texture2D(tex.width, tex.height, TextureFormat.RGBA32, false);
    7.     convertedTex.SetPixels32(tex.GetPixels32());
    8.     tex = convertedTex;
    9. }
    10.  
    which is fine and it works, but I profiled it and the time it takes is not insignificant.

    Anyhoo, is there a more efficient way of loading PNG files directly to RGBA32, or more efficient way of converting? I tried using Graphics.ConvertTexture, but it did not succeed. I assume it is because RGBA32 is not listed in as a RenderTextureFormat ( as per the documentation for Graphics.ConvertTexture ) GetRawTextureData<byte> instead, but it would be nice to get the raw texture data in a color struct.

    As I write this, I realized that I can create my own ARGB32 struct and use it like such...
    Code (CSharp):
    1.  
    2.         public struct ColorARGB32
    3.         {
    4.             public byte a;
    5.             public byte r;
    6.             public byte g;
    7.             public byte b;
    8.         }
    9. ...
    10. var pixels = GetRawTextureData<ColorARGB32>();
    11.  
    which should do the trick. However, I'll post this anyway in case y'all have a better idea, or in case someone else can use this info.
     
  2. Develax

    Develax

    Joined:
    Nov 14, 2017
    Posts:
    67
    I think it's worth destroying your old texture:
    Code (CSharp):
    1. Object.Destroy(tex);