iPhone上如何从BitmapContext中取出ARGB组件?
我正在尝试使用以下代码从 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
首先,您正在泄漏内存,pixelData 内存永远不会被释放。
对于您的使用,最好让 CGContext 调用来管理内存。 只需传递 NULL iso PixelData,只要您保持上下文的引用计数,
CGBitmapContextGetData(context)
将保持有效。您使用 alpha 就好像它是最后一个条目(RGBA,而不是 ARGB),在创建上下文时使用它,或者调整
alphaAtX
代码。 我不确定你是否想要预乘,如果只是为了检查 alpha 值,你不需要。总而言之:
将上下文作为成员变量,初始化为 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:
with context being a member variable, initialized to NULL, will already be a step in the right direction.
首先,我将检查从
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 surecontext != NULL
). I'd also check to make sure your originally loaded image is valid (so, make sureimg != 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 thepixelData
pointer you passed in in the first place. You should alsoCGContextRelease
your context before leaving yourinitWithImage:
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 youralphaAtX:y:
function.Does any of that help?