web-dev-qa-db-ja.com

iOSのCALayerからのUIImage

私のアプリケーションでは、CALayerを作成しました(サブレイヤーがいくつかある-CALayerはサブレイヤーとして追加された形状で構成されています)。

サーバーにアップロードできるUIImageを作成しようとしています(このためのコードがあります)。ただし、CALayerUIImageに追加する方法がわかりません。

これは可能ですか?

39
Brett

レイヤーを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!
}
106
Todd Yandell

トッドの答えは正しいですが、網膜スクリーンの場合は少し違いがあります:

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

私はこれに基づいて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)
9
Heberti Almeida

コンテキストのエラーチェックが少し行われた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()
  }
}
5
Justin Wright