views:

114

answers:

3

im trying to combine two images into a single image. unfortunately this has to be done very quickly in response to a user sliding a UISlider. i can combine the two images into a single image no problem. but the way I'm doing it is horribly slow. the sliders stick and jump rather frustratingly. i don't think i can throw the code into a background thread because i would run out of threads to quickly. i haven't actually tired that yet. below is my code. any ideas on how to speed it up would be helpful.

UIGraphicsBeginImageContext(CGSizeMake(bodyImage.theImage.image.size.width * 1.2, bodyImage.theImage.image.size.height * 1.2));

 [bodyImage.theImage.image drawInRect: 
  CGRectMake(-2 + ((bodyImage.theImage.image.size.width * 1.2) - bodyImage.theImage.image.size.width)/2, 
    kHeadAdjust, 
    bodyImage.theImage.image.size.width * bodyImage.currentScale, 
    bodyImage.theImage.image.size.height * bodyImage.currentScale)];

 if(isCustHead)
 {
  [Head.theImage.image drawInRect: CGRectMake((bodyImage.theImage.image.size.width * 1.2 - headWidth)/2 - 11,
             0, 
             headWidth * 0.92, 
             headWidth * (Head.theImage.image.size.height/Head.theImage.image.size.width) * 0.92)];
 }
 else 
 {
  [Head.theImage.image drawInRect: CGRectMake((bodyImage.theImage.image.size.width * 1.2 - (headWidth * defaultHeadAdjust))/2 - 10,
             0, 
             (headWidth * defaultHeadAdjust * 0.92), 
             (headWidth * defaultHeadAdjust) * (Head.theImage.image.size.height/Head.theImage.image.size.width) * 0.92)];
 }

 drawSurface.theImage.image = UIGraphicsGetImageFromCurrentImageContext();

 UIGraphicsEndImageContext();
A: 

I don't have a lot of time to answer, but one thing you'll want to do is move your drawing to a NSOperation and use a performOnMainThread: to notify when done.

Each time your slider moves, tell the NSOperationQueue to cancel it's operations. That way if the user is sliding really fast, you're not drawing only to immediately toss it away.

When the perform is done, store the image in the NSOperation subclass you made, and pass that to the main thread, where you can apply the image to the layer contents.

This will help your performance no matter how fast your code is, especially with spazztic users.

For image rendering, you might want to consider making a custom offscreen bitmap and rendering into it. Also, try caching a lot of your math, especially if it is not changing much.

The less you do, the faster it will go.

Also remove any NSLog's you might have, those really slow things down. I use a macro to NSLog only when a flag is set in a configuration (so I have a debug + log config)

Steve Riggins
+1  A: 

This ought to be pretty fast, actually. If your images are really large, you might want to cache screen-resolution versions of them for use in the rendering loop.

But really, there's no need to do any of this drawing yourself, in the general case. Create separate CALayers for the two images, add them both to a view, and let CoreGraphics handle the drawing.

Mark Bessey
I think that is the main solution to this problem, let the OS do the blend either through CoreGraphics or directly through OpenGl
Harald Scheirich
A: 

Not specific to iPhone. Just a thought:

How about ALPHA-blending the 2 images??

OR

Display the 2 images one on top of the other (upper one being 50% transparent).

CVS-2600Hertz