Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

9-slice scaling/stretching in the background, using Cocoa on iOS

I want to stretch an image using "9-slice" scaling, where only the centre of the image is scaled. Exactly like UIImage'sstretchableImageWithLeftCapWidth method, however I want to do this in a background thread. I understand that this method can only be used in the gui thread.

I'm developing on iOS / iPad / iPhone.

Does anyone have a code snippet, or know of a library that can do this? I'm trying to not re-invent the wheel!

Some related references I've found useful:

CGContext docs:

  • http://developer.apple.com/library/mac/#documentation/GraphicsImaging/Reference/CGContext/Reference/reference.html

Nice blog entry on drawing in the background:

  • http://joris.kluivers.nl/iphone-dev/?p=BackgroundImageProcessing

Rotating an image using CGContext:

  • http://blog.coriolis.ch/2009/09/04/arbitrary-rotation-of-a-cgimage/
like image 483
TJez Avatar asked Oct 10 '22 18:10

TJez


1 Answers

Since iOS 4, some parts of UIKit are thread-safe; I believe UIGraphics functions and UIImage drawing should work.

If you need to support iOS 3, then it's a bit more difficult. If you want to avoid UIKit entirely (possibly wise), then you'll need to pass the background thread a CGImageRef. There are additional things you might need to worry about; I'm assuming scale is 1 and imageOrientation is portrait.

  1. Create a context: CGBitmapContextCreate()
  2. Create your sub-images: CGImageCreateWithImageInRect().
  3. Draw each sub-image to the right place: CGContextDrawImage()
  4. Get the image from the context: CGBitmapContextCreateImage()
  5. Release the necessary things and return the CGImageRef to the main thread.
  6. In the main thread, use +[UIImage imageWithCGImage:] or +imageWithCGImage:scale:orientation: (note that in the latter case, images with scale 2 only seem to support portrait orientations; I'm not sure why).

Also note that it's significantly better to stick the image in a UIImageView and set contentStretch appropriately, since then the scaling is done on the GPU.

like image 72
tc. Avatar answered Oct 20 '22 06:10

tc.