2010-10-31 19 views
6

Należy zauważyć, że to pytanie dotyczy około CGLayer (którego zwykle używa się do rysowania poza ekranem), nie chodzi o CALayer.Jaki jest poprawny kod, aby zapisać CGLayer jako plik PNG?

W iOS, jaki jest poprawny kod, aby zapisać plik CGLayer jako plik PNG? Dzięki!

To znowu CGLayer, a nie CALayer.

pamiętać, że CAN NOT użycie UIGraphicsGetImageFromCurrentImageContext.

(Z dokumentacji: "Możesz nazywać UIGraphicsGetImageFromCurrentImageContext tylko wtedy, gdy na podstawie kontekstu bitmapy-grafika jest obecny kontekst graficzny").

pamiętać, że CAN NOT użycie renderInContext :. renderInContext: jest wyłącznie dla CALayers. CGLayers są zupełnie inne.

Jak zatem przekonwertować CGLayer na obraz PNG? Lub w jaki sposób renderować CGLayer do bitmapy w jakiś sposób (oczywiście można wtedy łatwo zapisać jako obraz).


Później ... Ken odpowiedział na to trudne pytanie. Wkleję w długim przykładowy kod, który może pomóc ludziom. Jeszcze raz dziękuję Ken! Niesamowity!

-(void)drawingExperimentation 
{ 
// this code uses the ASTOUNDING solution by KENNYTM -- Oct/Nov2010 
// 
// create a CGLayer for offscreen drawing 
// note. for "yourContext", ideally it should be a context from your screen, ie the 
// context you "normally get" in one of your drawRect routines associated with 
// drawing to the screen normally. 
// UIGraphicsGetCurrentContext() also normally works but you could have colorspace woes 

// so create the CGLayer called notepad... 

CGLayerRef notepad = CGLayerCreateWithContext(yourContext,CGSizeMake(1500,1500), NULL); 
CGContextRef notepadContext = CGLayerGetContext(notepad); 

// you can for example write an image in to notepad 
CGImageRef imageExamp = [[UIImage imageWithContentsOfFile: 
    [[NSBundle mainBundle] pathForResource:@"smallTestImage" ofType:@"png"] ] CGImage]; 
CGContextDrawImage(notepadContext, CGRectMake(100,100, 50,50), imageExamp); 

// setting the colorspace may or may not be relevant to you 
CGContextSetFillColorSpace(notepadContext, CGColorSpaceCreateDeviceRGB()); 

// you can draw to notepad as much as you like in the normal way 
// don't forget to push it's context on and off your work space so you can draw to it 

UIGraphicsPushContext(notepadContext); 

// set the colors 
CGContextSetRGBFillColor(notepadContext, 0.15,0.25,0.35, 0.45); 
// draw rects 
UIRectFill(CGRectMake(x,y,w,h)); 
// draw ovals, filled stroked or whatever you wish 
UIBezierPath* d = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(x,y,w,h)]; 
[d fill]; 
// draw cubic and other curves 
UIBezierPath *longPath; 
longPath.lineWidth = 42; 
longPath.lineCapStyle = kCGLineCapRound; 
longPath.lineJoinStyle = kCGLineJoinRound; 
[longPath moveToPoint:p]; 
[longPath addCurveToPoint:q controlPoint1:r controlPoint2:s]; 
[longPath addCurveToPoint:a controlPoint1:b controlPoint2:c]; 
[longPath addCurveToPoint:m controlPoint1:n controlPoint2:o]; 
[longPath closePath]; 
[longPath stroke]; 

UIGraphicsPopContext(); 

// so now you have a nice CGLayer. 

// how to save it to a file? 

// you can save it to a file using the amazing KENNY-TM-METHOD !!! 

UIGraphicsBeginImageContext(CGLayerGetSize(notepad)); 
CGContextRef rr = UIGraphicsGetCurrentContext(); 
CGContextDrawLayerAtPoint(rr, CGPointZero, notepad); 
UIImage* ii = UIGraphicsGetImageFromCurrentImageContext(); 
NSData* pp = UIImagePNGRepresentation(ii); 
[pp writeToFile:@"foo.png" atomically:YES]; 
UIGraphicsEndImageContext(); 

// you may prefer to look at it like this: 

UIGraphicsBeginImageContext(CGLayerGetSize(notepad)); 
CGContextDrawLayerAtPoint(UIGraphicsGetCurrentContext(), CGPointZero, notepad); 
[UIImagePNGRepresentation(UIGraphicsGetImageFromCurrentImageContext()) writeToFile:@"foo.png" atomically:YES]; 
UIGraphicsEndImageContext(); 

// there are three clever steps in the KENNY-TM-METHOD: 
// - start a new UIGraphics image context 
// - CGContextDrawLayerAtPoint which can, in fact, draw a CGLayer 
// - just use the usual UIImagePNGRepresentation to convert to a png 

// done! a miracle 

// if you are testing on your mac-simulator, you'll find the file 
// simply in the main drive directory 
return; 
} 

Odpowiedz

9

dla iPhone OS, powinno być możliwe, aby narysować CGLayer na CGContext a następnie przekonwertować do UIImage, które następnie mogą być zakodowany w PNG i zapisane.

CGSize size = CGLayerGetSize(layer); 
UIGraphicsBeginImageContext(size); 
CGContextRef ctx = UIGraphicsGetCurrentContext(); 
CGContextDrawLayerAtPoint(ctx, CGPointZero, layer); 
UIImage* image = UIGraphicsGetImageFromCurrentImageContext(); 
NSData* pngData = UIImagePNGRepresentation(image); 
[pngData writeToFile:... atomically:YES]; 
UIGraphicsEndImageContext(); 

(nie badane)

+0

@Joe: Zobacz aktualizację. – kennytm

+0

Ken, który jest niesamowity - wyrzuciłeś go z wody. Świetna robota. Musisz być bardzo zadowolony z siebie :) Niesamowite .. Jeszcze raz dziękuję – Fattie

+0

bountied! dzięki – Fattie

Powiązane problemy