web-dev-qa-db-fra.com

UIImage de CALayer dans iOS

Dans mon application, j'ai créé un CALayer (avec quelques sous-couches - le CALayer est composé de formes ajoutées en tant que sous-couches).

J'essaye de créer un UIImage que je pourrai télécharger sur un serveur (j'ai le code pour cela). Cependant, je ne peux pas comprendre comment ajouter le CALayer à un UIImage.

Est-ce possible?

39
Brett

On dirait que vous voulez rendre votre couche dans une UIImage. Dans ce cas, la méthode ci-dessous devrait faire l'affaire. Ajoutez simplement ceci à votre vue ou à votre classe de contrôleur, ou créez une catégorie sur CALayer.

Obj-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!
}
106
Todd Yandell

La réponse de Todd est correcte, mais pour les écrans Retina, il devrait y avoir une petite différence:

- (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
Ömer Faruk Gül

J'ai créé une extension Swift pour ceci:

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

L'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)
9
Heberti Almeida

Version Swift 3 avec un peu de vérification d'erreur pour le contexte.

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