Is UIImageJPEGRepresentation() thread safe?
You can use UIImageJPEGRepresentation() in the background (I'm using it this way in a current project).
However what you can't do is create a UIImage the way you are doing in the background, the [UIImage imagewithCGImage]
call must be doing in the main thread (as a rule of thumb all UIKit calls should be done on the main thread).
This seems like a case where you might need nested blocks.
Edit: My own code I have found does call [UIImage imagewithCGImage]
while in a background thread, but I am still suspicious that might cause issues in some cases. But my code does work.
Edit2: I just noticed you are resizing the image, UIImage+Resize. There's a very nice class linked to in this post, that has been built to do that in a robust way:
http://vocaro.com/trevor/blog/2009/10/12/resize-a-uiimage-the-right-way/
You should really read that whole page to understand the nuances of resizing images. As I said, I do use that from a background thread even though part of what it does inside is what you were doing.
Edit3: If you are running on iOS4 or later, you may want to look into using the ImageIO framework to output images, which is more likely to be thread safe:
http://developer.apple.com/graphicsimaging/workingwithimageio.html
Example code for that is hard to find, here's a method that saves a PNG image using ImageIO (based on the code in "Programming With Quartz:2D and PDF graphics in Mac OS X):
// You'll need both ImageIO and MobileCoreServices frameworks to have this compile#import <ImageIO/ImageIO.h>#import <MobileCoreServices/MobileCoreServices.h>void exportCGImageToPNGFileWithDestination( CGImageRef image, CFURLRef url){ float resolution = 144; CFTypeRef keys[2]; CFTypeRef values[2]; CFDictionaryRef options = NULL; // Create image destination to go into URL, using PNG CGImageDestinationRef imageDestination = CGImageDestinationCreateWithURL( url, kUTTypePNG, 1, NULL); if ( imageDestination == NULL ) { fprintf( stderr, "Error creating image destination\n"); return; } // Set the keys to be the X and Y resolution of the image keys[0] = kCGImagePropertyDPIWidth; keys[1] = kCGImagePropertyDPIHeight; // Create a number for the DPI value for the image values[0] = CFNumberCreate( NULL, kCFNumberFloatType, &resolution ); values[1] = values[0]; // Options dictionary for output options = CFDictionaryCreate(NULL, (const void **)keys, (const void **)values, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); CFRelease(values[0]); // Adding the image to the destination CGImageDestinationAddImage( imageDestination, image, options ); CFRelease( options ); // Finalizing writes out the image to the destination CGImageDestinationFinalize( imageDestination ); CFRelease( imageDestination );}
Apple's official position is that no part of UIKit is thread-safe. However, the rest of your code appears to be Quartz-based, which is thread-safe when used in the manner you use it.
You can do everything on a background thread, then do the call to UIImageJPEGRepresentation()
back on main:
// ...CGImageRef ref = CGBitmapContextCreateImage(bitmap);dispatch_async(dispatch_get_main_queue(), ^ { NSData *finalData = UIImageJPEGRepresentation([UIImage imageWithCGImage:ref], 1.0); [self.delegate sendNSDataBack:finalData];});CGContextRelease(bitmap);CGImageRelease(ref);
I think it is thread-safe because I do the similar things to resize an UIImage, or store image data to database in the background thread. And, the main-thread sometimes is named to UI thread. Anything about updating a screen should be executed on the UI thread. But, the UIImage is an object to store image data. It is not sub-classed from UIView. So, it is thread-safe.