0
+(UIImage*) createCGImageFromFile:(NSString*)inName
{
    if(!inName || [inName length]==0)
        return  NULL;

    // use the data provider to get a CGImage; release the data provider
    CGImageRef image= NULL;
    CGFloat scale = 1.0f;
    CGDataProviderRef dataProvider = NULL;

    NSString *fileName = nil;
    NSString *path = nil;
    if([Utilities isRetinaDevice])
    {
        NSString *extenstion = [inName pathExtension];
        NSString *stringWithoutPath = [inName stringByDeletingPathExtension];
        fileName = [NSString stringWithFormat:@"/Images/%@@2x.%@",stringWithoutPath,extenstion];
        path = [[[NSBundle mainBundle] resourcePath] stringByAppendingString:fileName];
        dataProvider = CGDataProviderCreateWithFilename([path UTF8String]);
        if(dataProvider)
        {
            image = CGImageCreateWithPNGDataProvider(dataProvider, NULL, NO,kCGRenderingIntentDefault);
            CGDataProviderRelease(dataProvider);
            if(image)
            {
                scale = 2.0f;
            }
        }
    }

    if(image == NULL) //Try normal image
    {
        fileName =  [NSString stringWithFormat:@"/Images/%@",inName];
        path = [[[NSBundle mainBundle] resourcePath] stringByAppendingString:fileName];
        dataProvider = CGDataProviderCreateWithFilename([path UTF8String]);
        if(dataProvider)
        {
            image = CGImageCreateWithPNGDataProvider(dataProvider, NULL, NO,kCGRenderingIntentDefault);
            CGDataProviderRelease(dataProvider);
        }
    }

    // make a bitmap context of a suitable size to draw to, forcing decode
    size_t width = CGImageGetWidth(image);
    size_t height = CGImageGetHeight(image);
    unsigned char *imageBuffer = (unsigned char *)malloc(width*height*4);

    CGColorSpaceRef colourSpace = CGColorSpaceCreateDeviceRGB();

    CGContextRef imageContext =
    CGBitmapContextCreate(imageBuffer, width, height, 8, width*4, colourSpace,
                          kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Little);

    CGColorSpaceRelease(colourSpace);

    // draw the image to the context, release it
    CGContextDrawImage(imageContext, CGRectMake(0, 0, width, height), image);
    CGImageRelease(image);

    // now get an image ref from the context
    CGImageRef cgImageRef = CGBitmapContextCreateImage(imageContext);

    CGContextRelease(imageContext);
    free(imageBuffer);

    UIImage *outImage = nil;
    if(cgImageRef)
    {
        outImage = [[UIImage alloc] initWithCGImage:cgImageRef scale:scale orientation:UIImageOrientationUp];
        CGImageRelease(cgImageRef);
    }

    return outImage;//Need to release by the receiver
}

Earlier the function was not loading retina images since i was not appending @2x to the image path, i thought that apple itself will take care. Now I modified the code to load @2x images and created UIImage using scale factor, am I missing something in above code? Is it fine?

P.S. Currently I am not facing any problem using this code but I am not 100% sure

Chandan Shetty SP
  • 5,087
  • 6
  • 42
  • 63
  • What is the point of this method? It returns a UIImage, which you can just do with imageNamed. It's title suggests it returns a CGImage, which you can get directly from the UIImage object. – jrturton Nov 22 '12 at 07:47
  • I using this method in background thread... so I am loading image data using CG calls instead of UI – Chandan Shetty SP Nov 22 '12 at 09:48
  • You can use imageNamed: in a background thread. – jrturton Nov 22 '12 at 10:04
  • If I use imageNamed it causing small glitch... http://stackoverflow.com/questions/1815476/cgimage-uiimage-lazily-loading-on-ui-thread-causes-stutter – Chandan Shetty SP Nov 22 '12 at 14:30

1 Answers1

0

I would use UIImage to load it (it will correct the path) That will greatly simply your code

THEN get a CGImage from it (UIImage is basically just a thin wrapper around CG so thats no real overhead)

then proceed with your code - it looks ok to me

Daij-Djan
  • 49,552
  • 17
  • 113
  • 135