【发布时间】:2010-08-10 23:53:24
【问题描述】:
在我的应用程序中,我创建了一个CALayer(带有一些子层 - CALayer 由作为子层添加的形状组成)。
我正在尝试创建一个UIImage,我将能够将其上传到服务器(我有此代码)。
但是,我不知道如何将CALayer 添加到UIImage。
这可能吗?
【问题讨论】:
标签: ios objective-c uiimageview uiimage calayer
在我的应用程序中,我创建了一个CALayer(带有一些子层 - CALayer 由作为子层添加的形状组成)。
我正在尝试创建一个UIImage,我将能够将其上传到服务器(我有此代码)。
但是,我不知道如何将CALayer 添加到UIImage。
这可能吗?
【问题讨论】:
标签: ios objective-c uiimageview uiimage calayer
听起来你想将你的图层渲染成 UIImage。在这种情况下,下面的方法应该可以解决问题。只需将其添加到您的视图或控制器类,或在 CALayer 上创建一个类别。
Obj-C
- (UIImage *)imageFromLayer:(CALayer *)layer
{
UIGraphicsBeginImageContextWithOptions(layer.frame.size, NO, 0);
[layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *outputImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return outputImage;
}
斯威夫特
func imageFromLayer(layer:CALayer) -> UIImage {
UIGraphicsBeginImageContextWithOptions(layer.frame.size, layer.isOpaque, 0)
layer.render(in: UIGraphicsGetCurrentContext()!)
let outputImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return outputImage!
}
【讨论】:
UIGraphicsBeginImageContextWithOptions(layer.frame.size, YES, 0);
UIGraphicsBeginImageContextWithOptions(layer.frame.size, layer.opaque, 0);
Todd 的回答是正确的,但是对于视网膜屏幕应该有一点区别:
- (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;
}
【讨论】:
UIGraphicsBeginImageContextWithOptions() 的scale arg 指定0 默认使用UIScreen.mainScreen.scale。 (根据文档,“应用于位图的比例因子。如果您指定的值为 0.0,则比例因子将设置为设备主屏幕的比例因子。”) 您的答案在功能上与@Todd Yandell 相比没有任何改进。
我为此创建了一个 Swift 扩展:
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
}
}
用法:
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)
【讨论】:
带有一点上下文错误检查的 Swift 3 版本。
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()
}
}
【讨论】:
defer处理UIGraphicsEndImageContext()