我需要从单个灰度图像(红色、橙色、黄色等)创建 12 个彩色图像
源图像实际上是PNG、RGBA:
我正在使用我找到的一个库(https://github.com/PaulSolt/UIImage-Conversion/ https://github.com/PaulSolt/UIImage-Conversion/)将 UIImage 分解为 RGBA 字节数组,然后逐像素处理该数组,并使用相同的库重新构建新的 UIImage。
这是我的代码:
- (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;
}
问题是我没有恢复 Alpha 通道——它在各处将其设置为不透明。
如果我只是将源图像传递回第一行,它就会正确渲染,因此问题不在于源图像。
如果我检查第一个像素的 alpha 分量,我发现在该过程中的所有点上它都是 0(即透明),正如它应该的那样。正如您所看到的,我什至进行了额外的测试 - 一旦获得最终的 UIImage,我再次将其分解为 RGBA 位图并检查相同的元素。仍然是0。
所以看来convertUIImageToBitmapRGBA8方法中一定存在一些错误。看起来生成的 UIImage 上必须有一些设置,这使得它认为它到处都是不透明的。
但是查看这个方法的源代码(https://github.com/PaulSolt/UIImage-Conversion/blob/master/ImageHelper.m https://github.com/PaulSolt/UIImage-Conversion/blob/master/ImageHelper.m-- 整个库只是这个文件及其标头)我看不出问题可能出在哪里。
这是渲染输出:
正如您所看到的,C 在 G 之前渲染,在 F 之前渲染,因此它的两侧都被矩形剪掉了。