2010-08-10 15 views
35

Nella mia applicazione, ho creato un CALayer (con alcuni sottolivelli - il CALayer è composto da forme aggiunte come sottolivelli).UIImage di CALayer - iPhone SDK

Sto cercando di creare un UIImage che sarò in grado di caricare su un server (ho il codice per questo). Tuttavia, non riesco a capire come aggiungere CALayer a UIImage.

È possibile? Qualche consiglio sarebbe eccellente e molto apprezzato.

Molte grazie, Brett

risposta

97

Sembra che si desidera rendere il vostro livello in un UIImage. In tal caso, il metodo seguente dovrebbe fare il trucco. Basta aggiungere questo alla tua vista o classe controller, o creare una categoria su CALayer.

- (UIImage *)imageFromLayer:(CALayer *)layer 
{ 
    UIGraphicsBeginImageContextWithOptions(layer.frame.size, NO, 0); 

    [layer renderInContext:UIGraphicsGetCurrentContext()]; 
    UIImage *outputImage = UIGraphicsGetImageFromCurrentImageContext(); 

    UIGraphicsEndImageContext(); 

    return outputImage; 
} 
+0

soluzione Flawless ... Thanks :) – oberthelot

+0

Ancora un'altra risposta Vorrei poter upvote due volte. Grazie Todd. –

+1

Exchange per 'UIGraphicsBeginImageContextWithOptions (layer.frame.size, YES, 0);' – Jonny

18

risposta di Todd è corretta, tuttavia per gli schermi retina ci dovrebbe essere una piccola differenza:

- (UIImage *)imageFromLayer:(CALayer *)layer 
{ 

    if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)]) 
     UIGraphicsBeginImageContextWithOptions([layer frame].size, NO, [UIScreen mainScreen].scale); 
    else 
     UIGraphicsBeginImageContext([layer frame].size); 

    [layer renderInContext:UIGraphicsGetCurrentContext()]; 
    UIImage *outputImage = UIGraphicsGetImageFromCurrentImageContext(); 

    UIGraphicsEndImageContext(); 

    return outputImage; 
} 
+0

specificando '0' per' UIGraphicsBeginImageContextWithOptions() il parametro 'scale' arg lo usa come predefinito' UIScreen.mainScreen.scale'. _ (Per i documenti, "Il fattore di scala da applicare alla bitmap. Se si specifica un valore di 0.0, il fattore di scala viene impostato sul fattore di scala della schermata principale del dispositivo.") _ La risposta non offre alcun miglioramento funzionale @ Todd Yandell's. –

5

ho creato un'estensione Swift base per questo:

extension UIImage { 
    class func imageWithLayer(layer: CALayer) -> UIImage { 
     UIGraphicsBeginImageContextWithOptions(layer.bounds.size, layer.opaque, 0.0) 
     layer.renderInContext(UIGraphicsGetCurrentContext()!) 
     let img = UIGraphicsGetImageFromCurrentImageContext() 
     UIGraphicsEndImageContext() 
     return img 
    } 
} 

L'utilizzo:

var gradient = CAGradientLayer() 
gradient.colors = [UIColor.redColor().CGColor, UIColor.blueColor().CGColor] 
gradient.frame = CGRect(x: 0, y: 0, width: 200, height: 200) 

let image = UIImage.imageWithLayer(gradient) 
4

Versione Swift 3 con un po 'di controllo degli errori per il contesto.

extension UIImage { 
    class func image(from layer: CALayer) -> UIImage? { 
    UIGraphicsBeginImageContextWithOptions(layer.bounds.size, 
    layer.isOpaque, UIScreen.main.scale) 

    defer { UIGraphicsEndImageContext() } 

    // Don't proceed unless we have context 
    guard let context = UIGraphicsGetCurrentContext() else { 
     return nil 
    } 

    layer.render(in: context) 
    return UIGraphicsGetImageFromCurrentImageContext() 
    } 
} 
+0

Puoi usare 'differisci' per gestire il' UIGraphicsEndImageContext() ' –

+0

Grande suggerimento. Aggiornato per posticipo dell'utente. –