ARGB和kCGImageAlphaPremultipliedFirst格式。为什么像素颜色存储为(255-数据)?

时间:2014-04-02 11:55:45

标签: argb image-formats color-coding

我使用

创建图像
UIGraphicsBeginImageContextWithOptions(image.size, NO, 0);
[image drawInRect:CGRectMake(0, 0, image.size.width, image.size.height)];
// more code - not relevant - removed for debugging
image = UIGraphicsGetImageFromCurrentImageContext(); // the image is now ARGB
UIGraphicsEndImageContext();

然后我尝试找到一个像素的颜色(使用Minas Petterson的代码从这里开始:Get Pixel color of UIImage)。 但由于图像现在是ARGB格式,我不得不用以下代码修改代码:

    alpha = data[pixelInfo];
    red = data[(pixelInfo + 1)];
    green = data[pixelInfo + 2];
    blue = data[pixelInfo + 3];

然而这不起作用。

问题在于(例如)是一个红色像素,在RGBA中将表示为 1001 (实际上是255 0 0 255,但为了简单起见,我使用0在图像中表示为 0011 而不是(我认为) 1100 。 有什么想法吗?我做错了吗?

PS。我必须使用的代码看起来必须如此:

alpha = 255-data[pixelInfo];
red = 255-data[(pixelInfo + 1)];
green = 255-data[pixelInfo + 2];
blue = 255-data[pixelInfo + 3];

1 个答案:

答案 0 :(得分:1)

那里出现了一些问题:

"在某些情况下,主要是OpenGL,术语" RGBA"实际上意味着颜色存储在内存中,使得R位于最低地址,G位于其后,B之后位于最后一位。 OpenGL将上述格式描述为" BGRA"在小端机器和" ARGB"在大端机器上。" (维基)

图形硬件由OS X / iOS上的OpenGL支持,所以我假设我们处理小端数据(英特尔/臂处理器)。因此,当格式为little-endian机器上的kCGImageAlphaPremultipliedFirst(ARGB)时,它是BGRA。但不要担心,有一种简单的方法可以解决这个问题。

假设它是ARGB,kCGImageAlphaPremultipliedFirst,每个组件8位,每个像素4个组件(这是UIGraphicsGetImageFromCurrentImageContext()返回的内容),请不要使用&t; t_care-endiannes:

- (void)parsePixelValuesFromPixel:(const uint8_t *)pixel
                       intoBuffer:(out uint8_t[4])buffer {
    static NSInteger const kRedIndex = 0;
    static NSInteger const kGreenIndex = 1;
    static NSInteger const kBlueIndex = 2;
    static NSInteger const kAlphaIndex = 3;

    int32_t *wholePixel = (int32_t *)pixel;
    int32_t value = OSSwapHostToBigConstInt32(*wholePixel); 
    // Now we have value in big-endian format, regardless of our machine endiannes (ARGB now).

    buffer[kAlphaIndex] = value & 0xFF;
    buffer[kRedIndex] = (value >> 8) & 0xFF;
    buffer[kGreenIndex] = (value >> 16) & 0xFF;
    buffer[kBlueIndex] = (value >> 24) & 0xFF;
}