UIView screenshot capture - slow performance

I have a Drawing App, I would like to take a picture of the Canvas UIView (both on-screen and off-screen), and then scale it. The code that I have for this is dialing damn forever on iPad 3. The simulator does not linger. Canvas 2048x2048.

Is there any other way I have to do this? Or is something missing from my code?

Thanks!

-(UIImage *) createScreenShotThumbnailWithWidth:(CGFloat)width{ // Size of our View CGSize size = editorContentView.bounds.size; //First Grab our Screen Shot at Full Resolution UIGraphicsBeginImageContext(size); [editorContentView.layer renderInContext:UIGraphicsGetCurrentContext()]; UIImage *screenShot = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); //Calculate the scal ratio of the image with the width supplied. CGFloat ratio = 0; if (size.width > size.height) { ratio = width / size.width; } else { ratio = width / size.height; } //Setup our rect to draw the Screen shot into CGSize newSize = CGSizeMake(ratio * size.width, ratio * size.height); //Send back our screen shot return [self imageWithImage:screenShot scaledToSize:newSize]; } 
+4
source share
2 answers

Did you use the Time Profiler tool (Product menu → Profile) to check where you spend most of your time in your code? (use it with your device, of course, not a simulator to have realistic profiling). I would suggest that this is not in the image capture part that you quoted in your question, but in the imageWithImage:scaledToSize: scale method.

Instead of displaying the image at full size in the context, and then scaling the image to the final size , you should render the layer in the context directly at the expected size, applying some affine transformation to the context .

So just use CGContextConcatCTM(someScalingAffineTransform); on UIGraphicsGetCurrentContext() immediately after your line UIGraphicsBeginImageContext(size); to apply a scaling affine transform that will render the layer rendered at a different scale / size.

This way, it will be displayed directly as the expected size, which will be much faster, instead of being displayed at the 100% level, and then you will have to re-scale it over time

+2
source

Thanks to AliSoftware . Here is the code I ended up in:

  -(UIImage *) createScreenShotThumbnailWithWidth:(CGFloat)width{ if (IoUIDebug & IoUIDebugSelectorNames) { NSLog(@"%@ - %@", INTERFACENAME, NSStringFromSelector(_cmd) ); } // Size of our View CGSize size = editorContentView.bounds.size; //Calculate the scal ratio of the image with the width supplied. CGFloat ratio = 0; if (size.width > size.height) { ratio = width / size.width; } else { ratio = width / size.height; } CGSize newSize = CGSizeMake(ratio * size.width, ratio * size.height); //Create GraphicsContext with our new size UIGraphicsBeginImageContext(newSize); //Create Transform to scale down the Context CGAffineTransform transform = CGAffineTransformIdentity; transform = CGAffineTransformScale(transform, ratio, ratio); //Apply the Transform to the Context CGContextConcatCTM(UIGraphicsGetCurrentContext(),transform); //Render our Image into the the Scaled Graphic Context [editorContentView.layer renderInContext:UIGraphicsGetCurrentContext()]; //Save a copy of the Image of the Graphic Context UIImage* screenShot = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return screenShot; } 
0
source

All Articles