Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iPhone: Changing CGImageAlphaInfo of CGImage

I have a PNG image that has an unsupported bitmap graphics context pixel format. Whenever I attempt to resize the image, CGBitmapContextCreate() chokes on the unsupported format

I receive the following error (error formatted for easy reading):

CGBitmapContextCreate: unsupported parameter combination:      8 integer bits/component;      32 bits/pixel;      3-component colorspace;      kCGImageAlphaLast;      1344 bytes/row. 

The list of supported pixel formats definitely does not support this combination. It appears I need to redraw the image and move the alpha channel information to kCGImageAlphaPremultipliedFirst or kCGImageAlphaPremultipliedLast.

I have no idea how to go about doing this.

There is nothing unusual about the PNG file and it isn't corrupted. It works in all other context just fine. I encountered this error just by chance but obviously my users might have similarly formatted files so I will have to check my app's imported images and correct for this problem.

like image 672
TechZen Avatar asked Mar 16 '10 18:03

TechZen


2 Answers

Yeah, I had problems with 8 bit (indexed) .PNGs. I had to convert it to a more native image to perform graphics operations. I essentially did something like this:

- (UIImage *) normalize {      CGColorSpaceRef genericColorSpace = CGColorSpaceCreateDeviceRGB();     CGContextRef thumbBitmapCtxt = CGBitmapContextCreate(NULL,                                                           self.size.width,                                                           self.size.height,                                                           8, (4 * self.size.width),                                                           genericColorSpace,                                                           kCGImageAlphaPremultipliedFirst);     CGColorSpaceRelease(genericColorSpace);     CGContextSetInterpolationQuality(thumbBitmapCtxt, kCGInterpolationDefault);     CGRect destRect = CGRectMake(0, 0, self.size.width, self.size.height);     CGContextDrawImage(thumbBitmapCtxt, destRect, self.CGImage);     CGImageRef tmpThumbImage = CGBitmapContextCreateImage(thumbBitmapCtxt);     CGContextRelease(thumbBitmapCtxt);         UIImage *result = [UIImage imageWithCGImage:tmpThumbImage];     CGImageRelease(tmpThumbImage);      return result;     } 
like image 97
Alfons Avatar answered Sep 22 '22 19:09

Alfons


Here's an updated version of the method from Alfons answer to account for screen scale, and also some silly errors with decimals in floating point values of the image size as described in unsynchronized's comment from the original answer.

SCREEN_SCALE is a macro that returns either 1.0 if scale isn't defined or whatever the device scale actually is ([UIScreen mainScreen].scale).

- (UIImage *) normalize {      CGSize size = CGSizeMake(round(self.size.width*SCREEN_SCALE), round(self.size.height*SCREEN_SCALE));     CGColorSpaceRef genericColorSpace = CGColorSpaceCreateDeviceRGB();     CGContextRef thumbBitmapCtxt = CGBitmapContextCreate(NULL,                                                           size.width,                                                           size.height,                                                           8, (4 * size.width),                                                           genericColorSpace,                                                           kCGImageAlphaPremultipliedFirst);     CGColorSpaceRelease(genericColorSpace);     CGContextSetInterpolationQuality(thumbBitmapCtxt, kCGInterpolationDefault);     CGRect destRect = CGRectMake(0, 0, size.width, size.height);     CGContextDrawImage(thumbBitmapCtxt, destRect, self.CGImage);     CGImageRef tmpThumbImage = CGBitmapContextCreateImage(thumbBitmapCtxt);     CGContextRelease(thumbBitmapCtxt);         UIImage *result = [UIImage imageWithCGImage:tmpThumbImage scale:SCREEN_SCALE orientation:UIImageOrientationUp];     CGImageRelease(tmpThumbImage);      return result;     } 
like image 22
psy Avatar answered Sep 21 '22 19:09

psy