- Home /
Texture2D.GetPixel returning wrong colours
I used Paint(dot)NET to create bitmaps where each pixel colour represents a type of block, where I'd then use a script to read each pixel and create a block based on that.
I saved using both uncompressed PNG and BMP and when I use Texture2D, it works fine for images of about size 20x20, but once I start moving up to about 60x60, it gets less and less accurate. I have also tried with bypassing sRGB sampling, no change in results.
I tried using both Color and Color32, however they both return similar inaccuracies when accounting for the different systems.
I do have the texture imported to not resize if it's not a power by 2 along a dimension, and I have tried with textures that are a power of 2 along both dimensions. Accuracy of the results improved slightly when the image was a power of 2 along both dimensions.
I am ignoring alpha channels and not using them to compare, so they are not the issue. I am only comparing the RGB parts.
To put the errors into perspective, a pixel that was (155,155,0) when I made in Paint(dot)NET was read as (156,154,0) when the image was 20x20. When the image was 60x60 or even 64x64, I could not identify anywhere in my console logs anything that resembled the original colour.
When using Color32, I had margins of error for +/- 2 and tried with +/- 64. For 20x20 images, +/- 2 was good enough. For 64x64 images, +/- 64 would still have troubles identifying an area that was completely white (not on an image that was completely white).
If I had to guess, it's like Unity was trying to apply some sort of antialiasing.
I have also opened the texture from after applying these files in Unity to check and they were exactly as I made them, so no errors were made into the files. It seems like Unity is just reading them wrong.
In summary:
I have set the test textures to readable
I have set them not to resize if not a power of 2 along a dimension, and have created test textures that are powers of 2
I have tried with and without sRGB sampling
I have tested with both Color and Color32
I have tested with 'wiggle space' of 25% on both
GetPixel is still having troubles
So, I guess my question is how do I get Unity to read the texture 'absolutely'?
Edit: Changed it to Paint(dot)NET so it doesn't make weird URLs.
Answer by Gizmoi · Jan 28, 2013 at 12:51 AM
I had a similar issue myself, mine was solved by making them non power of two though. Have you tried making it a GUI texture, as in selecting GUI as the import type, also, I had issues with the format. Try changing it in advanced, I seem to remember that RGBA 32 and ARGB 32 were the ones that worked.
GUI type didn't work, but cursor didn't work. Not to take away from the nifty idea, this answer isn't technically correct, the idea behind it got me to an idea that was.
Setting it to cursor let it read it absolutely.
It appears that the fundamental issue is that (DXT1) compression must be turned off. Switching it to GUI is a convenient way to do this.
I'm using color to represent prefab blocks, and this was a tricky configuration to track down and resolve. Here's hoping this helps.
Answer by Bunny83 · Jan 27, 2013 at 10:50 PM
If you want to read the actual pixels, make sure you set "Non power of 2" to "None", otherwise your texture will be rescaled to the nearest power of two size (..., 16, 32, 64, ...)
I have tried that. Things are roughly where they're meant to be, its just reading colours from between slightly to, what might as well be, completely wrong.
Do you use GetPixel or GetPixelBilinear? GetPixelBilinear will filter the pixel bilinear so it interpolates between the closest 4 pixels.
I never had problems reading pixels from a texture. Are you sure you use the right x, y position? Just in case you don't know the origin ( 0,0 ) of a texture is the bottom left corner.
Yes, i'm pretty sure ;) Texture space and camera / screen space have the same layout. X goes from left to right and Y from bottom to top and since Untiy is left-handed Z goes into the screen However texture space is only 2D.
GetPixels or GetPixels32 gives a hint "pixels are laid out left to right, bottom to top (i.e. row after row)"
The only thing that has it's origin "top left" is the GUI system. Everything else is referenced from the screen origin which is bottom left. Even Input.mousePosition is relative to bottom left. The GUI mouse position (Event.current.mousePosition) is relative to the top left corner.
Answer by Tioboon · Jan 20 at 07:21 PM
I was with the same problem, i have to setup it in photoshop to export in RGB32 and change some configurations from sprite in unity:
Your answer
Follow this Question
Related Questions
create readable colour map 1 Answer
Get set of Pixels from PolygonCollider2d Position 0 Answers
Combining 2 black-white textures 2 Answers
Vertex Color to Texture2D?? 0 Answers
blending colors on a texture: shader, render texture, or other 2 Answers