2010-10-12 5 views
8

J'essaye de découper une région d'un UIView, en UIImage pour réutiliser plus tard.UIImage d'une région de UIView

Je travaille sur ce code de quelques extraits:

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 » est le UIView que je suis écrêtage et _finalImage est le UIImage que je veux.

Le code fonctionne sans problème, mais il est plutôt lent. Je crois que certaines performances pourraient être obtenues en prenant juste la partie de l'écran directement à l'étape A.

Je cherche quelque chose comme renderInContext: withRect: ou UIGraphicsGetImageFromCurrentImageContextWithRect() hehe.

n'a pas encore trouvé encore rien :(, s'il vous plaît aidez-moi si vous connaissez une alternative

+0

pouvez-vous reformater? difficile à lire – Rudiger

Répondre

6

Cette méthode clips une région de la vue en utilisant moins de mémoire et de temps CPU:

-(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; 
} 
0

Vous pouvez essayer pixelliser le UIView premier.

view.layer.shouldRasterize = YES; 

J'ai un succès limité en utilisant cela, mais est en train de dire que je fais la même chose que vous (plus la ligne ci-dessus) et ça marche bien, dans quel contexte faites-vous ça? C'est peut-être votre problème de performance

EDIT: Vous pouvez également essayer d'utiliser les limites de la vue au lieu du cadre de la vue. ne sont pas toujours les mêmes.

+0

Le contexte «principal» je pense. Je crée un nouveau contexte sur le thread principal. : S – almosnow

0

Version Swift de @ phix23 solution. ajouter échelle

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 
}