将CGLayer保存为PNG文件的正确代码是什么? [英] What's the correct code to save a CGLayer as a PNG file?

查看:135
本文介绍了将CGLayer保存为PNG文件的正确代码是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请注意,这个问题是关于 CGLayer (您通常用于绘制屏幕外),它与CALayer无关。

Please note that this question is about CGLayer (which you typically use to draw offscreen), it is not about CALayer.

In iOS,将 CGLayer 保存为PNG文件的正确代码是什么?谢谢!

In iOS, what's the correct code to save a CGLayer as a PNG file? Thanks!

再次,这是CGLayer,而不是CALayer。

Again, that's CGLayer, not CALayer.

请注意 CAN NOT 使用UIGraphicsGetImageFromCurrentImageContext。

Note that you CAN NOT use UIGraphicsGetImageFromCurrentImageContext.

(来自文档,只有当基于位图的图形上下文是当前图形上下文时才能调用UIGraphicsGetImageFromCurrentImageContext 。)

(From the documentation, "You can call UIGraphicsGetImageFromCurrentImageContext only when a bitmap-based graphics context is the current graphics context.")

请注意, CAN NOT 使用renderInContext:。 renderInContext:严格用于CALayers。 CGLayers完全不同。

Note that you CAN NOT use renderInContext:. renderInContext: is strictly for CALayers. CGLayers are totally different.

那么,你怎么能真正将CGLayer转换成PNG图像呢?或者实际上,如何以某种方式将CGLayer渲染到位图中(当然,您可以轻松地将其保存为图像)。

So, how can you actually convert a CGLayer to a PNG image? Or indeed, how to render a CGLayer in to a bitmap in some way (of course you can then easily save as an image).

后来......肯回答了这个棘手的问题。我将粘贴一个可以帮助人们的长示例代码。再次感谢Ken!太棒了!

Later ... Ken has answered this difficult question. I will paste in a long example code that may help people. Thanks again Ken! Amazing!

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


推荐答案

对于iPhone OS,它应该可以在CGContext上绘制CGLayer,然后转换为UIImage,然后可以将其编码为PNG并保存。

For iPhone OS, it should be possible to draw a CGLayer on a CGContext and then convert into a UIImage, which can then be encoded into PNG and saved.

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

(未经测试)

这篇关于将CGLayer保存为PNG文件的正确代码是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆