I’m currently trying to load a texture from a png file that I stored locally. I mostly want to use this texture as a crude leveleditor, with for example (in rgba32) [0,0,0,255] being stone, [1,0,0,255] being wood, [2,0,0,255] being iron, etc. Therefore the values of the png need to be 1:1 the same in the texture in memory as the png on disk. (I also don’t want to predefine the levels in Unity, so creating texture resources is out.)
If I do this via the Unity Editor it works. However if I try and load the texture programatically it doesn’t, as the pixel values are not perfectly preservered. For example [1,0,0,255] and [2,0,0,255] are both mapped to [1,0,0,255], or another example would be [245,0,0,255] being mapped to [244,0,0,255].
To test this I created a 32x32 32-bit png with the upper left 10 pixels going horizontaly from [0,0,0,255] to [10,0,0,255]. Then I exectued the code below, which should load the image and save it with a different name as well as output the pixel colors in memory.
var tmpimg = new Texture2D(32, 32, TextureFormat.RGBA32, false); // Has the same effect as var tmpimg = new Texture2D(32, 32);
tmpimg.LoadImage(File.ReadAllBytes("Assets/orig.png"));
Debug.Log(tmpimg.GetPixel(0, 31).ToString()
+ "; " + tmpimg.GetPixel(1, 31).ToString()
+ "; " + tmpimg.GetPixel(2, 31).ToString()
+ "; " + tmpimg.GetPixel(3, 31).ToString());
File.WriteAllBytes("Assets/saved.png", tmpimg.EncodeToPNG());
Executing this I get a debug output of
Which shows me that both [1,0,0,255] and [2,0,0,255] are mapped to the same rgba value and [3,0,0,255] is mapped to [2,0,0,255] (obviously in float representation but that shouldn’t matter I think) already in memory. I also get the saved.png which when I look at it in Paint.NET shows more mismatches.
So now my question is, am I doing something wrong? Or is LoadImage not guaranteed to preserve color values? And what can I do about it?
(If someone wants to test it for themselves I attached the whole unity project as a zip.)
3138049–237978–TextureLoadTest.zip (21.2 KB)