I ran into this issue a couple hours ago working on the IPhone sdk:
See the darker borders around the image?
It’s a png image and that’s was supposed to be a gradient of alpha. So why am I getting this strange stuff around it?
Well that’s because that alpha isn’t 0 or 1 or 0 or 255.
The first thing I found out is that XCode grabs the png images and multiplies the RGB component with the alpha. So you can understand now why only 0 or 1 works right? Everything in between get’s changed. This is why Apple recommends using PNG over JPGS, although they consume more space they are altered for speed.
This is refereed as using images with pre-multiplied alpha.
If you don’t care about this and just want to use regular alpha blend one quick fix up for this is on each image load to reset the correct RGB values and maintain the A component
int pixelcount = width*height; // Image data is a pointer for your image data int count = width*height; unsigned char* off = (unsigned char*)imageData; for( int i=0; i < count; ++i ) { unsigned char alpha = off[3]; if( alpha!=255 || alpha!=0 ) { off[0] = ((int)off[0])*255/alpha; off[1] = ((int)off[1])*255/alpha; off[2] = ((int)off[2])*255/alpha; } off += 4; } |
There may be other solutions but this won’t have any impact on the game, just when loading images. Let me know if you find any other solution.
EDIT: Quick note here: this is not the correct way to deal with pre-multiplied alpha but a patching. XNA recently embraced pre multiplied alpha to avoid this issues. More here (Thanks Elisée Maurer)
I think you might be dealing with premultiplied alpha the wrong way. You should embrace the chances made by Xcode to your PNGs (instead of reverting them) and change your rendering code to handle premultiplied alpha. This is the correct way to blend multiple pictures on top of each other to get correct colors.
This is a good read on the subject: http://blogs.msdn.com/b/shawnhar/archive/2009/11/06/premultiplied-alpha.aspx
Hi Elisée.
Indeed this is just a quick fix-up since the problem relies on the drawing code itself as you mentioned. This is just for those who want to make it work without much hassle, even more when .pvr files don’t have the same behavior. I think I’ll change the post warning that this is not the correct way to deal with pre-multiplied alpha. Thanks