2009-07-11 13 views
21

Ich möchte ein UIImage-Objekt aus dem aktuellen Grafikkontext erstellen. Genauer gesagt ist mein Anwendungsfall eine Ansicht, auf die der Benutzer Linien zeichnen kann. Sie können inkrementell zeichnen. Nachdem sie fertig sind, möchte ich ein UIImage erstellen, um ihre Zeichnung darzustellen. HierWie erstelle ich ein UIImage aus dem aktuellen Grafikkontext?

ist, was drawRect: wie für mich sieht jetzt:

- (void)drawRect:(CGRect)rect 
{ 
CGContextRef c = UIGraphicsGetCurrentContext(); 

CGContextSaveGState(c); 
CGContextSetStrokeColorWithColor(c, [UIColor blackColor].CGColor); 
CGContextSetLineWidth(c,1.5f); 

for(CFIndex i = 0; i < CFArrayGetCount(_pathArray); i++) 
{ 
    CGPathRef path = CFArrayGetValueAtIndex(_pathArray, i); 
    CGContextAddPath(c, path); 
} 

CGContextStrokePath(c); 

CGContextRestoreGState(c); 
} 

... wo _pathArray vom Typ CFArrayRef ist und bevölkert wird jedes Mal touchesEnded: aufgerufen wird. Beachten Sie auch, dass drawRect: möglicherweise mehrmals aufgerufen wird, wenn der Benutzer zeichnet.

Wenn der Benutzer fertig ist, möchte ich ein UIImage-Objekt erstellen, das den Grafikkontext darstellt. Irgendwelche Vorschläge, wie man das macht?

+0

beide Antworten unter Arbeit. Beachten Sie, dass es einen funktionalen Unterschied zwischen den beiden gibt. Das bedeutet, dass beim Rendern der Ebene im Bildkontext auch der Hintergrund der Ebene gerendert wird. Aufruf drawRect: direkt nicht (in meinem Fall ist es egal). Ich gehe mit dem CALayer renderInContext Ansatz wegen der Komplexität beim Aufruf von drawRect: direkt (Siehe http://lists.apple.com/archives/Coco-dev/2002/Apr/msg01846.html für Details). Vielen Dank! – figelwump

Antwort

42

Sie müssen den Grafikkontext Setup zuerst:

UIGraphicsBeginImageContext(myView.bounds.size); 
[myView.layer renderInContext:UIGraphicsGetCurrentContext()]; 
viewImage = UIGraphicsGetImageFromCurrentImageContext(); 
UIGraphicsEndImageContext(); 
7

UIImage * image = UIGraphicsGetImageFromCurrentImageContext();

Wenn Sie herumhalten müssen, achten Sie darauf, es zu behalten!

EDIT: Wenn Sie die Ausgabe von DrawRect in ein Bild speichern möchten, erstellen Sie einfach einen Bitmap-Kontext mit UIGraphicsBeginImageContext und rufen Sie Ihre DrawRect-Funktion mit dem neuen Kontext gebunden. Dies ist einfacher als das Speichern des CGContextRef, mit dem Sie in drawRect arbeiten - weil diesem Kontext möglicherweise keine Bitmap-Informationen zugeordnet sind.

UIGraphicsBeginImageContext(view.bounds.size); 
[view drawRect: [myView bounds]]; 
UIImage * image = UIGraphicsGetImageFromCurrentImageContext(); 
UIGraphicsEndImageContext(); 

Sie können auch den von Kelvin erwähnten Ansatz verwenden. Wenn Sie ein Bild aus einer komplexeren Ansicht wie UIWebView erstellen möchten, ist seine Methode schneller. Beim Zeichnen der Ebene der Ansicht muss die Ebene nicht aktualisiert werden, da nur Bilddaten von einem Puffer in einen anderen verschoben werden müssen!

+0

Danke für die Antwort, scheint aber nicht zu funktionieren. Ich fügte die Zeile hinzu: \t _signatureImage = UIGraphicsGetImageFromCurrentImageContext(); ... wobei _signatureImage eine beibehaltene Eigenschaft ist. Das zurückgegebene Objekt ist null. Gemäß den Dokumenten ist UIGraphicsGetImageFromCurrentImageContext() nur für den Fall vorgesehen, dass der aktuelle Kontext ein Bitmap-Kontext ist. In meiner aktuellen Implementierung von drawRect: Ich glaube nicht, dass das der Fall ist. Die Dokumente erwähnen die Verwendung von UIGraphicsBeginImageContext(), aber ich bin nicht sicher, wie das in meinem Fall gilt, da DrawRect mehrmals aufgerufen werden kann. – figelwump

2

Swift Version

func createImage(from view: UIView) -> UIImage { 
     UIGraphicsBeginImageContext(view.bounds.size) 
     view.layer.renderInContext(UIGraphicsGetCurrentContext()!) 
     let viewImage = UIGraphicsGetImageFromCurrentImageContext() 
     UIGraphicsEndImageContext() 

     return viewImage 
    } 
Verwandte Themen