2009-07-11 14 views
21

Mi piacerebbe creare un oggetto UIImage dal contesto grafico corrente. Più specificamente, il mio caso d'uso è una vista in cui l'utente può disegnare linee. Possono disegnare in modo incrementale. Dopo aver finito, mi piacerebbe creare una UIImage per rappresentare il loro disegno.Come creare un UIImage dal contesto grafico corrente?

Ecco cosa drawRect: appare come per me, ora:

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

... dove _pathArray è di tipo CFArrayRef, ed è popolato ogni volta touchesEnded: viene richiamato. Si noti inoltre che drawRect: può essere richiamato più volte, come l'utente disegna.

Quando l'utente ha terminato, mi piacerebbe creare un oggetto UIImage che rappresenti il ​​contesto grafico. Qualche suggerimento su come fare questo?

+0

Entrambe le risposte qui sotto lavoro. Si noti che esiste una differenza funzionale tra i due, vale a dire che il rendering del livello nel contesto dell'immagine renderà anche lo sfondo del livello; chiamare drawRect: direttamente non (nel mio caso non importa). Vado con l'approccio renderInContext CALayer a causa delle complessità con la chiamata drawRect: direttamente (per ulteriori dettagli, vedere http://lists.apple.com/archives/Cocoa-dev/2002/Apr/msg01846.html). Grazie! – figelwump

risposta

42

è necessario impostare il contesto grafico prima:

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

UIImmagine * image = UIGraphicsGetImageFromCurrentImageContext();

Se è necessario mantenere image in giro, assicurarsi di mantenerlo!

MODIFICA: se si desidera salvare l'output di drawRect su un'immagine, è sufficiente creare un contesto bitmap utilizzando UIGraphicsBeginImageContext e richiamare la funzione drawRect con il nuovo contesto associato. È più facile fare che salvare il CGContextRef con cui stai lavorando all'interno di drawRect - perché a tale contesto potrebbero non essere associate le informazioni bitmap.

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

È anche possibile utilizzare l'approccio citato da Kelvin. Se vuoi creare un'immagine da una vista più complessa come UIWebView, il suo metodo è più veloce. Disegnare il livello della vista non richiede l'aggiornamento del livello, ma richiede semplicemente lo spostamento dei dati dell'immagine da un buffer all'altro!

+0

Grazie per la risposta, tuttavia, non sembra funzionare. Ho aggiunto la riga: \t _signatureImage = UIGraphicsGetImageFromCurrentImageContext(); ... dove _signatureImage è una proprietà mantenuta. L'oggetto restituito è nullo. Secondo i documenti, UIGraphicsGetImageFromCurrentImageContext() è destinato all'uso solo se il contesto corrente è un contesto bitmap. Nella mia attuale implementazione di drawRect: non credo che sia così. I documenti menzionano l'uso di UIGraphicsBeginImageContext(), ma non sono sicuro di come si applichi nel mio caso perché drawRect può essere invocato più volte. – figelwump

2

Swift versione

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

     return viewImage 
    }