ios iOS中来自CALayer的UIImage

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3454356/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 17:31:53  来源:igfitidea点击:

UIImage from CALayer in iOS

iosobjective-cuiimageviewuiimagecalayer

提问by Brett

In my application, I have created a CALayer(with a few sublayers - the CALayer is composed of shapes added as sublayers).

在我的应用程序中,我创建了一个CALayer(带有几个子层 - CALayer 由添加为子层的形状组成)。

I am trying to create a UIImagethat I will be able to upload to a server (I have the code for this). However, I can't figure out how to add the CALayerto a UIImage.

我正在尝试创建一个UIImage我可以上传到服务器的文件(我有这个代码)。然而,我无法弄清楚如何将添加CALayerUIImage

Is this possible?

这可能吗?

回答by Todd Yandell

Sounds like you want to render your layer into a UIImage. In that case, the method below should do the trick. Just add this to your view or controller class, or create a category on CALayer.

听起来您想将图层渲染为 UIImage。在这种情况下,下面的方法应该可以解决问题。只需将此添加到您的视图或控制器类,或在 CALayer 上创建一个类别。

Obj-C

对象-C

- (UIImage *)imageFromLayer:(CALayer *)layer
{
  UIGraphicsBeginImageContextWithOptions(layer.frame.size, NO, 0);

  [layer renderInContext:UIGraphicsGetCurrentContext()];
  UIImage *outputImage = UIGraphicsGetImageFromCurrentImageContext();

  UIGraphicsEndImageContext();

  return outputImage;
}

Swift

迅速

func imageFromLayer(layer:CALayer) -> UIImage {
    UIGraphicsBeginImageContextWithOptions(layer.frame.size, layer.isOpaque, 0)
    layer.render(in: UIGraphicsGetCurrentContext()!)
    let outputImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    return outputImage!
}

回答by ?mer Faruk Gül

Todd's answer is correct, however for retina screens there should be a little difference:

托德的回答是正确的,但是对于视网膜屏幕应该有一点区别:

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

回答by Heberti Almeida

I have created a Swift extension based for this:

我已经创建了基于这个迅捷的扩展:

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

The usage:

用法:

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)

回答by Justin Wright

Swift 3 version with a little bit of error checking for context.

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