I'm trying to clip a region of an UI开发者_如何学CView
, into a UIImage
for later reuse.
I've worked out this code from some snippets:
CGRect _frameIWant = CGRectMake(100, 100, 100, 100);
UIGraphicsBeginImageContext(view.frame.size);
[view.layer renderInContext:UIGraphicsGetCurrentContext()];
//STEP A: GET AN IMAGE FOR THE FULL FRAME
UIImage *_fullFrame = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
//STEP B: CLIP THE IMAGE
CGImageRef _regionImage = CGImageCreateWithImageInRect([_fullFrame CGImage], _frameIWant);
UIImage *_finalImage = [UIImage imageWithCGImage:_regionImage];
CGImageRelease(_regionImage);
'view' is the UIView
which I'm clipping and _finalImage
is the UIImage
I want.
The code works without problem, however is kind of slow. I believe that some performance could be gained by taking just the portion of the screen directly in Step A.
I'm looking for something like renderInContext: withRect:
or UIGraphicsGetImageFromCurrentImageContextWithRect()
hehe.
Still haven't found anything yet :(, please help me if you know of some alternative.
This method clips a region of the view using less memory and CPU time:
-(UIImage*)clippedImageForRect:(CGRect)clipRect inView:(UIView*)view
{
UIGraphicsBeginImageContextWithOptions(clipRect.size, YES, 1.f);
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextTranslateCTM(ctx, -clipRect.origin.x, -clipRect.origin.y);
[view.layer renderInContext:ctx];
UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return img;
}
You could try rasterizing the UIView first:
view.layer.shouldRasterize = YES;
I have limited success using this but is saying that I'm doing the same thing as you (plus the above line) and it works fine. In what context are you doing this in? It may be your performance issue.
EDIT: Also you could try using the bounds of the view instead of the frame of the view. They are not always the same.
Swift version of @phix23 solution . adding scale
func clippedImageForRect(clipRect: CGRect, inView view: UIView) -> UIImage {
UIGraphicsBeginImageContextWithOptions(clipRect.size, true, UIScreen.mainScreen().scale);
let ctx = UIGraphicsGetCurrentContext();
CGContextTranslateCTM(ctx, -clipRect.origin.x, -clipRect.origin.y);
view.layer.renderInContext(ctx!)
let img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return img
}
精彩评论