I am trying to improve performance for the code I use to convert a png to grayscale.
I load image via Json, convert to texture, then grayscale at runtime going through each pixel and using GetPixels32/SetPixels32
. Memory use is too high for the many images I have so I'd like to use more efficient GetRawTextureData
.
However LoadImage
is returning a ARGB32 texture2d
which seems to be messing up then follow on use in GetRawTextureData
(RGB32).
It's confusing because png with LoadImage on Unity 2019.2 should be returning RGBA32 but for me it's returning ARGB32 which is what LoadImage legacy Unity 5.3 would have returned - not sure if a bug or documentation error.
Texture2D thisTexture = new Texture2D(1, 1, TextureFormat.RGBA32, false);
byte[] t = Convert.FromBase64String(imageString);//png image in string format
thisTexture.LoadImage(t);//Using Unity2019.2.2 result is ARGB32
When I convert image to grayscale I get a yellowish image and I think that's because GetRawTextureData
is RGB32 but LoadImage
returns ARGB32.
How can I replicate the LoadImage
process to get RGB32?
//convert texture
graph = thisTexture;
grayImg = new Texture2D(graph.width, graph.height, graph.format, false);
Debug.Log("grayImg format " + grayImg.format + " graph format " + graph.format);
Graphics.CopyTexture(graph, grayImg);
var data = grayImg.GetRawTextureData<Color32>();
int index = 0;
Color32 pixel;
for (int x = 0; x < grayImg.width; x++)
{
for (int y = 0; y < grayImg.height; y++)
{
pixel = data[index];
int p = ((256 * 256 + pixel.r) * 256 + pixel.b) * 256 + pixel.g;
int b = p % 256;
p = Mathf.FloorToInt(p / 256);
int g = p % 256;
p = Mathf.FloorToInt(p / 256);
int r = p % 256;
byte l = (byte) ((pixel.r ) + pixel.g + pixel.b);
Color32 c = new Color32(pixel.r, pixel.g, pixel.b, 1);
data[index++] = c;
}
}
// upload to the GPU
grayImg.Apply(false);
Revised code with LoadRawTextureData:
Texture2D thisTexture = new Texture2D(1, 1, TextureFormat.RGBA32, false);
byte[] t = Convert.FromBase64String(imageString);//png image in string format
thisTexture.LoadRawTextureData(t);//results in RGBA32 (Note: using either thisTexture.LoadImage(t); or thisTexture.LoadRawTextureData(t); when using LoadRawTextureData to set the pixels on the grayscale, the texture continues to be yellowish.
thisTexture.Apply();