0

我使用创建图像

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 到 1 值),在图像中表示为0011而不是(因为我想) 1100。任何想法为什么?难道我做错了什么?

PS。我必须使用的代码看起来必须是这样的:

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

1 回答 1

2

那里会出现一些问题:

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

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

假设它是 ARGB,kCGImageAlphaPremultipliedFirst,每个分量 8 位,每个像素 4 个分量(这就是 UIGraphicsGetImageFromCurrentImageContext() 返回的内容),don'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;
}
于 2014-10-10T09:55:33.677 回答