iPhone上如何从BitmapContext中取出ARGB组件?

发布于 2024-07-13 18:47:26 字数 1965 浏览 4 评论 0原文

我正在尝试使用以下代码从 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 { [超级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 数据。 关于代码有什么问题有什么想法吗?

I'm trying to get ARGB components from CGBitmapContext with the following codes:


-(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

}

When I try to store red/green/blue, they turn out to be always 240. And alpha is always 255.

So I think maybe something is wrong with the pointer. It could not return the correct ARGB data I want. Any ideas about what's wrong with the code?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

沉溺在你眼里的海 2024-07-20 18:47:26

首先,您正在泄漏内存,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);
[...]

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

First of all, you're leaking memory, the pixelData memory never gets freed.

For your usage, it's better to let the CGContext calls manage the memory. Simply pass NULL i.s.o. pixelData, and as long as you keep the reference count up on your context, the CGBitmapContextGetData(context) will remain valid.

You're using alpha as if it was the last entry (RGBA, not ARGB), use it as such in the creation of your context, or adapt the alphaAtX code. I'm not sure if you want premultiplied, if it's just to check alpha values, you don't.

All in all something like:

[...]
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);
[...]

with context being a member variable, initialized to NULL, will already be a step in the right direction.

煮酒 2024-07-20 18:47:26

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

如果你的context为nil,可能是因为你的图片尺寸不合理,或者是你的像素数据格式不可用。 尝试使用 kCGImageAlphaPremultipliedLast 来代替?

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

我还注意到您正在使用 kCGImageAlphaPremultipliedFirst。 这意味着 Alpha 分量在图像中位于第一个,而不是最后一个,因此您希望 alphaAtX:y: 函数中的 Alpha 分量的偏移量为 0。

这些有帮助吗?

First, I would check to see if the context returned from your CGBitmapContextCreate call is valid (that is, make sure context != NULL). I'd also check to make sure your originally loaded image is valid (so, make sure img != nil).

If your context is nil, it may be because your image size is unreasonable, or else your pixel data format is unavailable. Try using kCGImageAlphaPremultipliedLast instead?

Second, you don't need to use CGBitmapContextGetData - you can just use the pixelData pointer you passed in in the first place. You should also CGContextRelease your context before leaving your initWithImage: function to avoid a leak.

I also note that you're using kCGImageAlphaPremultipliedFirst. This means that the alpha component is first, not last, in your image, so you want an offset of 0 for the alpha component in your alphaAtX:y: function.

Does any of that help?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文