Tuesday, July 10, 2012

Loading Images using GCD


The main reason when a app become sluggish is when the main thread is blocked. To make the app to run smoother main thread should not be blocked. Since UIImage calls will not work on secondary thread if there are too many images to load then definitely the app become unresponsive while loading the images.

In the below method I am creating CGImageRef and then creating UIImage using that CGImageRef. Since CG calls will work in secondary thread you can put image loading part to GCD and leave it for GCD to take of image loading part without blocking main thread;)

+(CGImageRef) createCGImageFromFile  : (NSString*) inName
{  
    CGDataProviderRef dataProvider = CGDataProviderCreateWithFilename([[WSFUtilities getResourcePath:inName] UTF8String]);
 
    // use the data provider to get a CGImage; release the data provider
    CGImageRef 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 outputImage = CGBitmapContextCreateImage(imageContext);
 
    CGContextRelease(imageContext);
    free(imageBuffer);
 
    return outputImage;//Need to release by the receiver
}

-(void) setBackgroundImage
{
// other code...

  dispatch_queue_t loadingQueue = dispatch_queue_create("com.testing.imageloading",NULL);
  dispatch_async(loadingQueue, ^{
                CGImageRef outputImage = [self createCGImageFromFile:imagePath];
               dispatch_async(dispatch_get_main_queue(), ^{
               UIImage *image = [[UIImage alloc] initWithCGImage:outputImage];
               CGImageRelease(outputImage);
               yourImageView.image = image;
              [image release];});
              });      
 dispatch_release(loadingQueue);

//other code...
}

No comments:

Post a Comment