(iphone) is there a function call(UIImage related) I shouldn't do in non-main thread here?
I'm trying to create UIImage from background thread.
I wonder if any call I use here shouldn't be done in background. Thank you// defined below
CGContextRef context = CreateARGBBitmapContext(entireRect.size);
CGContextDrawImage(context, rect, originalImage.CGImage);
CGImageRef imageRef = CGBitmapContextCreateImage(context);
UIImage* img = [UIImage imageWithCGImage: imageRef];
CGImageRelease(imageRef);
CGContextRelease(context);
return img;
Where CreateARGBBitmapContext is defined as below.
CGContextRef CreateARGBBitmapContext(CGSize size)
{
CGContextRef context = NULL;
CGColorSpaceRef colorSpace;
void * bitmapData;
int bitmapByteCount;
int bitmapBytesPerRow;
// Get image width, height. We'll use the entire image.
size_t pixelsWide = size.width;
size_t pixelsHigh = size.height;
// Declare the number of bytes per row. Each pixel in the bitmap in this
// example is represented by 4 bytes; 8 bits each of red, green, blue, and 开发者_高级运维
// alpha.
bitmapBytesPerRow = (pixelsWide * 4);
// bitmapBytesPerRow = (int) round( pow( 2.0, trunc( log((double) bitmapBytesPerRow) / log(2.0) ) + 1.0 ) );
bitmapByteCount = (bitmapBytesPerRow * pixelsHigh);
// Use the generic RGB color space.
colorSpace = CGColorSpaceCreateDeviceRGB();
if (colorSpace == NULL)
{
fprintf(stderr, "Error allocating color space\n");
return NULL;
}
// Allocate memory for image data. This is the destination in memory
// where any drawing to the bitmap context will be rendered.
NSMutableData* mutableData = [NSMutableData dataWithLength: bitmapByteCount];
bitmapData = [mutableData mutableBytes];
if (bitmapData == NULL)
{
fprintf (stderr, "Memory not allocated!");
CGColorSpaceRelease( colorSpace );
return NULL;
}
// Create the bitmap context. We want pre-multiplied ARGB, 8-bits
// per component. Regardless of what the source image format is
// (CMYK, Grayscale, and so on) it will be converted over to the format
// specified here by CGBitmapContextCreate.
context = CGBitmapContextCreate (bitmapData,
pixelsWide,
pixelsHigh,
8, // bits per component
bitmapBytesPerRow,
colorSpace,
kCGImageAlphaPremultipliedFirst);
if (context == NULL)
{
fprintf (stderr, "Context not created!");
}
// Make sure and release colorspace before returning
CGColorSpaceRelease( colorSpace );
return context;
}
The following line should be in the main thread:
UIImage* img = [UIImage imageWithCGImage: imageRef];
The rest of the code looks like it would be ok to be in a different thread.
Any interaction with UIKit must be in the main thread. That's why creating a UIImage (or even something like setting the image of a UIImageView) must be done in the main thread. Fortunately, the heavy work, like downloading an image or probably even drawing one as you're doing, can be done in a separate thread. Then, you return to the main thread just to create the UIImage.
Using Grand Central Dispatch and some blocks, the following code might work for you:
dispatch_queue_t drawingQueue = dispatch_queue_create("Drawing image", NULL);
dispatch_async(drawingQueue, ^{
CGContextRef context = CreateARGBBitmapContext(entireRect.size);
CGContextDrawImage(context, rect, originalImage.CGImage);
CGImageRef imageRef = CGBitmapContextCreateImage(context);
dispatch_async(dispatch_get_main_queue(), ^{
UIImage* img = [UIImage imageWithCGImage: imageRef];
CGImageRelease(imageRef);
});
});
dispatch_release(drawingQueue);
If you're not familiar with Grand Central Dispatch, try googling it. I'm afraid I don't know of a good tutorial for it. Hope this is helpful.
CORRECTION:
My response above is wrong. The UIImage CAN be created in the main thread.
While most interaction with UIKit must be done in the main thread, there are a few exceptions, including UIImage, UIColor, UIFont and Core Graphics. These are all threadsafe.
(Note that I believe UIImageView is not threadsafe. So that if you were to set the image of a UIImageView, then you would have to return to the main thread. A variation of the above code would still be useful for interaction with other UIKit objects, and should not do any damage in this case-- other than unnecessarily complicating things.)
精彩评论