2010-08-10 3 views
35

In meiner Anwendung habe ich eine CALayer erstellt (mit einigen Unterschichten - der CALayer besteht aus Formen als Unterschichten hinzugefügt).UIImage von CALayer - iPhone SDK

Ich versuche eine UIImage zu erstellen, die ich auf einen Server hochladen kann (ich habe den Code dafür). Allerdings kann ich nicht herausfinden, wie Sie die CALayer zu einer UIImage hinzufügen.

Ist das möglich? Jeder Rat wäre ausgezeichnet und sehr geschätzt.

Vielen Dank, Brett

Antwort

97

Klingt wie Sie Ihre Schicht in eine UIImage machen möchten. In diesem Fall sollte die folgende Methode ausreichen. Fügen Sie dies einfach zu Ihrer Ansicht oder Controller-Klasse hinzu oder erstellen Sie eine Kategorie in CALayer.

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

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

    UIGraphicsEndImageContext(); 

    return outputImage; 
} 
+0

Makellose Lösung ... Danke :) – oberthelot

+0

Noch eine Antwort Ich wünschte, ich könnte zweimal upvote. Danke Todd. –

+1

Austausch für 'UIGraphicsBeginImageContextWithOptions (layer.frame.size, YES, 0);' – Jonny

18

Todds Antwort ist richtig, aber für Retina-Bildschirme sollte es ein kleiner Unterschied:

- (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

Angabe von '0' für' UIGraphicsBeginImageContextWithOptions() 's' scale' arg verwendet standardmäßig 'UIScreen.mainScreen.scale'. _ (Laut der Dokumentation, "Der Skalierungsfaktor für die Bitmap. Wenn Sie einen Wert von 0.0 angeben, wird der Skalierungsfaktor auf den Skalierungsfaktor des Hauptbildschirms des Geräts eingestellt.") _ Ihre Antwort bietet funktional keine Verbesserung gegenüber @ Todd Yandells. –

5

ich eine Swift-Erweiterung für diese Basis geschaffen haben:

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 
    } 
} 

Die Nutzung:

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

Swift 3 Version mit ein wenig Fehler beim Überprüfen auf Kontext.

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

Sie können 'defer' verwenden, um den' UIGraphicsEndImageContext() ' –

+0

großen Vorschlag zu behandeln. Auf Benutzer aufgeschoben aktualisiert. –