我需要从单个灰度图像(红橙黄等)
创建12个彩色图像源图像实际上是PNG,RGBA:
我正在使用我找到的库(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 - 整个库只是带有标题的文件)我看不出问题出在哪里。
这是渲染输出:
正如你所看到的,C在F之前的G之前被渲染,因此它被矩形夹在两边。
答案 0 :(得分:1)
alpha透明度问题已在最新的github push上修复。 https://github.com/PaulSolt/UIImage-Conversion/blob/master/ImageHelper.m
修复是使用以下代码,并在函数的bitmapInfo中对kCGImageAlphaPremultipliedLast进行逻辑OR运算。除了CGImageRef之外,还使用了bitmapInfo来增加CGContextRef。两个bitmapInfo参数的格式应该相同。
+ (UIImage *) convertBitmapRGBA8ToUIImage:(unsigned char *) buffer
withWidth:(int) width
withHeight:(int) height;
代码摘录:
CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault | kCGImageAlphaPremultipliedLast;
CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault;
CGImageRef iref = CGImageCreate(width,
height,
bitsPerComponent,
bitsPerPixel,
bytesPerRow,
colorSpaceRef,
bitmapInfo,
provider, // data provider
NULL, // decode
YES, // should interpolate
renderingIntent);
uint32_t* pixels = (uint32_t*)malloc(bufferLength);
if(pixels == NULL) {
NSLog(@"Error: Memory not allocated for bitmap");
CGDataProviderRelease(provider);
CGColorSpaceRelease(colorSpaceRef);
CGImageRelease(iref);
return nil;
}
CGContextRef context = CGBitmapContextCreate(pixels,
width,
height,
bitsPerComponent,
bytesPerRow,
colorSpaceRef,
bitmapInfo);
答案 1 :(得分:0)
我正在尝试使用该库,但在复制图像而不是正确的alpha通道中,我收到了一团糟。 broken image
代码:
UIImage *c = [UIImage imageNamed:@"head_diamond_c.png"];
unsigned char * rawData = [ImageHelper convertUIImageToBitmapRGBA8: c];
UIImage *copy = [ImageHelper convertBitmapRGBA8ToUIImage: rawData withWidth:c.size.width withHeight:c.size.height];
free(rawData);
itemImageView setImage:copy];