I need to create 12 coloured images from a single greyscale image ( red orange yellow etc )
Source image is actually a PNG, RGBA:
I'm using a library I found ( https://github.com/PaulSolt/UIImage-Conversion/ ) to break the UIImage into a RGBA byte array which I then process pixel by pixel, and use the same library to reconstitute a new UIImage.
This is my code:
- (UIImage*) cloneWithTint3: (CGColorRef) cgTint
{
enum { R, G, B, A };
// - - -
assert( CGColorGetNumberOfComponents( cgTint ) == 4 );
const float* tint = CGColorGetComponents( cgTint );
// - - -
int w = self.size.width;
int h = self.size.height;
int pixelCount = w * h;
uint8_t* data = [UIImage convertUIImageToBitmapRGBA8: self];
for( int i=0; i < pixelCount ; i++ )
{
int offset = i << 2; // same as 4 * i but faster
float in_r = data[ offset + R ];
float in_g = data[ offset + G ];
float in_b = data[ offset + B ];
// float in_a = data[ offset + A ];
if( i == 0 )
printf( "ALPHA %d ", data[ offset + A ] ); // corner pixel has alpha 0
float greyscale = 0.30 * in_r + 0.59 * in_g + 0.11 * in_b;
data[ offset + R ] = (uint8_t) ( greyscale * tint[ R ] );
data[ offset + G ] = (uint8_t) ( greyscale * tint[ G ] );
data[ offset + B ] = (uint8_t) ( greyscale * tint[ B ] );
}
UIImage* imageNew = [UIImage convertBitmapRGBA8ToUIImage: data
withWidth: w
withHeight: h ];
free( data );
// test corner pixel
{
uint8_t* test = [UIImage convertUIImageToBitmapRGBA8: self];
for( int i=0; i < 1 ; i++ )
{
int offset = i << 2;
// float in_r = test[ offset + R ];
// float in_g = test[ offset + G ];
// float in_b = test[ offset + B ];
// float in_a = data[ offset + A ];
printf( "ALPHA %d ", test[ offset + A ] ); // corner pixel still has alpha 0
}
free( test );
}
return imageNew;
}
Problem is that I'm not getting the alpha channel back -- it is setting it to opaque everywhere.
If I simply pass the source image back on the first line, it renders correctly, so the problem is not with the source image.
If I inspect the alpha component of the first pixel, I find it is 0 (ie transparent) at all points in the process, as it should be. I even put in an extra test as you can see -- once I have my final UIImage I again break it into a RGBA bitmap and inspect the same element. It is still 0.
So it seems there must be some bug in the convertUIImageToBitmapRGBA8 method. it looks like there must be some setting on the resultant UIImage which is making it think it is opaque everywhere.
But looking through the source code for this method ( https://github.com/PaulSolt/UIImage-Conversion/blob/master/ImageHelper.m -- the whole library is just this file with its header ) I cannot see where the problem might be.
This is the rendering output:
As you can see, the C was rendered before the G before the F, hence it is clipped on both sides by the rectangles.