1

I'm writing this Today Widget, that needs to display an image. I noticed, that every time the Widget loads, the image is redrawn. This takes about half a second. After some investigation, I found out, that the culprit is, that the image file is in the Indexed color space. So: my question is: How do I convert this file to something that the iPhone can display more efficiently? For instance, an RGB file. I would then save it to a new file, and load that new file in my UIImageView.

I played around a bit with CGImage, since I believe that is the solution direction, but I end up with a white UIImageView.

This is my code:

UIImage * theCartoon = [UIImage imageWithData:imageData];
    CGImageRef si = [theCartoon CGImage];
    CGDataProviderRef src = CGImageGetDataProvider(si);
    CGImageRef imageRef = CGImageCreateWithPNGDataProvider(src, NULL, NO, kCGRenderingIntentDefault);
    cartoon.image = [[UIImage alloc] initWithCGImage:imageRef];

Any suggestions on this approach? Some obvious misprogramming?

Sjakelien
  • 2,255
  • 3
  • 25
  • 43

2 Answers2

3

Try this

// The source image
CGImageRef image = theCartoon.CGImage;
CGSize size = CGSizeMake(CGImageGetWidth(image), CGImageGetHeight(image));

// The result image in RGB color space   
CGImageRef result = nil;

// Check color space
CGColorSpaceRef srcColorSpace = CGImageGetColorSpace(image);
if (CGColorSpaceGetModel(srcColorSpace) != kCGColorSpaceModelRGB) {
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGContextRef context = CGBitmapContextCreate(nil, size.width, size.height, 8, 0, colorSpace, kCGImageAlphaNoneSkipLast);

    CGRect rect = {CGPointZero, size};
    CGContextDrawImage(context, rect, image);
    result = CGBitmapContextCreateImage(context);

    CGContextRelease(context);
    CGColorSpaceRelease(colorSpace);
}
MintSet
  • 365
  • 3
  • 9
1

It's been a while since the question was asked, but for others who might need this, here is my solution:

-(UIImage *) convertIndexedColorSpaceToRGB:(UIImage *) sourceImage {

CGImageRef originalImageRef = sourceImage.CGImage;
const CGBitmapInfo originalBitmapInfo = CGImageGetBitmapInfo(originalImageRef);

// See: http://stackoverflow.com/questions/23723564/which-cgimagealphainfo-should-we-use
const uint32_t alphaInfo = (originalBitmapInfo & kCGBitmapAlphaInfoMask);
CGBitmapInfo bitmapInfo = originalBitmapInfo;
switch (alphaInfo)
{
    case kCGImageAlphaNone:
        bitmapInfo |= kCGBitmapByteOrder32Big | kCGImageAlphaNoneSkipLast;
        break;
    case kCGImageAlphaPremultipliedFirst:
    case kCGImageAlphaPremultipliedLast:
    case kCGImageAlphaNoneSkipFirst:
    case kCGImageAlphaNoneSkipLast:
        break;
    case kCGImageAlphaOnly:
    case kCGImageAlphaLast:
    case kCGImageAlphaFirst:
    { 
        return sourceImage;
    }
        break;
}

const CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
const CGSize pixelSize = CGSizeMake(sourceImage.size.width * sourceImage.scale, sourceImage.size.height * sourceImage.scale);

const CGContextRef context = CGBitmapContextCreate(NULL,
                                                   pixelSize.width,
                                                   pixelSize.height,
                                                   CGImageGetBitsPerComponent(originalImageRef),
                                                   pixelSize.width*4,
                                                   colorSpace,
                                                   bitmapInfo
                                                   );

CGColorSpaceRelease(colorSpace);

if (!context) return sourceImage;

const CGRect imageRect = CGRectMake(0, 0, pixelSize.width, pixelSize.height);
UIGraphicsPushContext(context);

// Flip coordinate system. See: http://stackoverflow.com/questions/506622/cgcontextdrawimage-draws-image-upside-down-when-passed-uiimage-cgimage
CGContextTranslateCTM(context, 0, pixelSize.height);
CGContextScaleCTM(context, 1.0, -1.0);
[sourceImage drawInRect:imageRect];
UIGraphicsPopContext();
const CGImageRef decompressedImageRef = CGBitmapContextCreateImage(context);
CGContextRelease(context);
UIImage *image = [UIImage imageWithCGImage:decompressedImageRef scale:[UIScreen mainScreen].scale orientation:UIImageOrientationUp];
CGImageRelease(decompressedImageRef);

return image; }
geco0ol
  • 11
  • 2