如何从iPhone的BitmapContext中提取ARGB组件?

3
我试图用以下代码从CGBitmapContext获取ARGB组件:

-(id) initWithImage: (UIImage*) image   //create BitmapContext with UIImage and use 'pixelData' as the pointer
{

        CGContextRef    context = NULL;
        CGColorSpaceRef colorSpace;
        int             bitmapByteCount;
        int             bitmapBytesPerRow;

        bitmapBytesPerRow   = (image.size.width * 4);                       
        bitmapByteCount     = (bitmapBytesPerRow * image.size.height);

        colorSpace = CGColorSpaceCreateDeviceRGB();                         
        pixelData = malloc( bitmapByteCount );      //unsigned char* pixelData is defined in head file
        context = CGBitmapContextCreate (pixelData,                         
                        image.size.width,
                        image.size.height,
                        8,    // bits per component
                        bitmapBytesPerRow,
                        colorSpace,
                        kCGImageAlphaPremultipliedFirst
                        );
        CGColorSpaceRelease( colorSpace );                                  

        CGContextDrawImage(context, CGRectMake(0, 0, image.size.width, image.size.height), image.CGImage);
        pixelData = CGBitmapContextGetData(context);
        return self;
}


-(float) alphaAtX:(int)x y:(int)y   //get alpha component using the pointer 'pixelData' 
{
    return pixelData[(y *width + x) *4 + 3];    //+0 for red, +1 for green, +2 for blue, +3 for alpha
}

-(void)viewDidLoad { [super viewDidLoad]; //加载图片 UIImage *img = [UIImage imageNamed:@"MacDrive.png"]; }

[self initWithImage:img];   //create BitmapContext with UIImage
float alpha = [self alphaAtX:20 y:20];  //store alpha component

当我尝试存储红/绿/蓝色时,它们总是变成240。而alpha始终为255。

所以我认为指针可能有问题。它无法返回我想要的正确ARGB数据。对于代码有什么错误的想法吗?


听起来你正在尝试做与我提出这个问题时类似的事情。标记为最佳答案的回答对我非常有帮助,希望它也能对你有所帮助。 - Olie
2个回答

2

首先,你的内存泄漏了,pixelData内存永远不会被释放。

在你的用法中,最好让CGContext调用管理内存。只需传递NULL代替pixelData,只要保持上下文的引用计数,CGBitmapContextGetData(context)就会保持有效。

你正在将alpha用作最后一个条目(RGBA,而不是ARGB),请在创建上下文时将其用作此类条目,或者修改alphaAtX代码。如果你只是想检查alpha值,那么无需进行预乘运算。

总的来说,可以这样写:

[...]
CGContextRelease(context);
context = CGBitmapContextCreate (NULL,                                                     
                                    image.size.width,
                                    image.size.height,
                                    8,    // bits per component
                                    bitmapBytesPerRow,
                                    colorSpace,
                                    kCGImageAlphaLast
                                    );
CGColorSpaceRelease( colorSpace );                                                                      

CGContextDrawImage(context, CGRectMake(0, 0, image.size.width, image.size.height), image.CGImage);
pixelData = CGBitmapContextGetData(context);
[...]

将上下文作为成员变量并初始化为NULL,这已经是朝着正确方向迈出的一步。


0

首先,我会检查从CGBitmapContextCreate调用返回的上下文是否有效(也就是说,确保context != NULL)。我还会检查一下你最初加载的图像是否有效(因此,请确保img != nil)。

如果您的上下文为nil,则可能是因为您的图像大小不合理,或者您的像素数据格式不可用。尝试改用kCGImageAlphaPremultipliedLast

其次,您不需要使用CGBitmapContextGetData - 您可以直接使用您在第一次传递的pixelData指针。在离开initWithImage:函数之前,您还应该CGContextRelease您的上下文以避免泄漏。

我还注意到您正在使用kCGImageAlphaPremultipliedFirst。这意味着alpha组件在您的图像中是first,而不是last,因此您希望在alphaAtX:y:函数中将alpha组件的偏移量设置为0。

这些有帮助吗?


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接