1

I'm trying to create a thumb preview of a PDF's pages and store them on disk as PNGs. This is supposed to run in a separate thread and not on the UI thread.

To achieve this I'm using CGContextRef to draw the PDF page, then get a CGImage from it, convert that to a UIImage, get a PNG from it (which will be NSData) and save that NSData to disk. All clear so far.

However CGImage and UIImage are a UI elements and should not be used on another thread - but I don't want to bring that image on screen ever. Is it okay to use them on another thread in that case? Or is there another way to render a PDF page preview directly to disk?

poupou
  • 43,413
  • 6
  • 77
  • 174
Krumelur
  • 32,180
  • 27
  • 124
  • 263
  • You can use `CGImage` and `UIImage` methods on background threads as long as you're running 4.0+ (you could always use `CGImage` on background threads). The only `UIImage` method you can't use from a background thread is `+imageNamed:`. – Jason Coco Apr 19 '12 at 14:45
  • @JasonCoco Do you have a link wrt `UIImage` ? Apple docs are not very precise about threading (beside telling **UIKit** isg enerally not thread-safe) and the iOS 4 changes from http://developer.apple.com/library/ios/#releasenotes/General/WhatsNewIniPhoneOS/Articles/iPhoneOS4.html do not specify I/O operations as being thread safe. – poupou Apr 19 '12 at 15:13
  • @poupou The documentation is out of date... the current documentation is in the link you provided. Look under UIKit Framework Enhancements about 2/3rds down the page. It's specific about drawing UIImages. It's also been stated directly by the core UIKit engineers both on the Developer Boards and in the WWDC'2010 talks. You should file bug reports on the old UIKit documentation that gives bad info. CoreGraphics and I/O have always been safe to use from background threads. – Jason Coco Apr 19 '12 at 15:24
  • @JasonCoco I do not doubt CoreGraphics and ImageIO (built on top of CoreGraphics), only **parts of** UIKit. The link I provided does not make it any clearer wrt to this question (`UIImage`'s I/O). Functions like `UIImagePNGRepresentation` are categorized as "Image Manipulation" (not I/O, nor drawing). I know some parts of UIKit are *now* thread-safe (sadly mostly thru rumours, not official documentation) but still I don't see how you can say `UIImage` is safe except for `+imageNamed:` (I was hoping for more *hard* data ;-) – poupou Apr 19 '12 at 15:43
  • 1
    @poupou Right, unfortunately the *hard* data is found by reading the official Apple Dev Forums or by watching the official Apple WWDC'2010 talks. In the forums the engineers often ask that developers create enhancement requests to fix the documentation, so I would make the same suggestion. `+imageNamed:` has to do with the caching, and was specified by one of the UIKit engineers on the forums. All the other functions (like `UIImagePNGRep...`) are wrappers around CoreGraphics functions, so they've always been safe, it was the drawing into the context from UIKit that used to cause the issues. – Jason Coco Apr 19 '12 at 15:58
  • I render and save images from pdf pages exactly like you do, in an app which is in the app store since over one year and never had any problems with that approach. – Kai Huppmann Apr 19 '12 at 16:01
  • @Kai: and you are also running this on a background thread? – Krumelur Apr 19 '12 at 16:40
  • Jep! I do a asynchronus http request for the PDF and so the Image processing right after the load of the document in the delegates thread. – Kai Huppmann Apr 19 '12 at 17:26

1 Answers1

1

UIKit is generally not thread safe (some calls are but it's very badly documented). OTOH CoreGraphics is thread safe. So avoiding UIImage and using only CGImage is the safest way to do image processing in a background thread.

See Saving CGImageRef to a png file? to save an CGImageRef as a PNG file.

Community
  • 1
  • 1
poupou
  • 43,413
  • 6
  • 77
  • 174
  • Although it seems to work, I will use the approach described in the link you posted because I'm afraif the MT 5.3 will give me an exception when it is checking for UI execution on a background thread. – Krumelur Apr 19 '12 at 16:41