Reputation: 16783
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?
Upvotes: 3
Views: 7232
Reputation: 17705
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.
Upvotes: 2
Reputation: 57168
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?
Upvotes: 0