私のアプリケーションでは、CALayer
を作成しました(サブレイヤーがいくつかある-CALayerはサブレイヤーとして追加された形状で構成されています)。
サーバーにアップロードできるUIImage
を作成しようとしています(このためのコードがあります)。ただし、CALayer
をUIImage
に追加する方法がわかりません。
これは可能ですか?
レイヤーを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!
}
トッドの答えは正しいですが、網膜スクリーンの場合は少し違いがあります:
- (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;
}
私はこれに基づいて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()
}
}