0

我需要从单个灰度图像(红橙黄等)创建 12 个彩色图像

源图像实际上是一个PNG,RGBA:

在此处输入图像描述

我正在使用我找到的一个库(https://github.com/PaulSolt/UIImage-Conversion/)将 UIImage 分解为一个 RGBA 字节数组,然后我逐个像素地处理它,并使用相同的库来重构一个新的用户界面图像。

这是我的代码:

- (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 在 G 之前在 F 之前渲染,因此它的两侧都被矩形剪裁了。

4

2 回答 2

1

alpha 透明度问题已在最新的 github 推送中修复。https://github.com/PaulSolt/UIImage-Conversion/blob/master/ImageHelper.m

修复方法是在函数的 bitmapInfo 中使用以下代码与 kCGImageAlphaPremultipliedLast 进行逻辑或运算。除了 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);
于 2011-08-24T16:23:03.617 回答
-1

我正在尝试使用该库,但是在复制图像而不是正确的 alpha 通道中,我收到一团糟。损坏的图像

代码:

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];
于 2011-12-03T11:39:37.780 回答