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"]; //load image

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

}

当我尝试存储红/绿/蓝时,结果总是 240。而 alpha 总是 255。

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

4

2 回答 2

2

首先,您正在泄漏内存,pixelData 内存永远不会被释放。

对于您的使用,最好让 CGContext 调用管理内存。只需传递 NULL iso 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);
[...]

context 是一个成员变量,初始化为 NULL,这已经是朝着正确方向迈出的一步。

于 2009-03-26T12:26:15.890 回答
0

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

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

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

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

这些有帮助吗?

于 2009-03-21T00:34:10.090 回答