Get Image from CALayer or NSView (swift 3)
<p>I was looking for a way to render a CALayer or NSView and get NSImage back.</p>
<p>I have a custom class, which is a subclass of NSView.
At the beginning I simply make a gradient layer to cover NSView.</p>
<pre><code>class ContentView: NSView {

   override func draw(_ dirtyRect: NSRect) {
      fillGradientLayer()
   }

   func fillGradientLayer() {
      gradientLayer = CAGradientLayer()
      gradientLayer.colors = [#colorLiteral(red: 0, green: 0.9909763549, blue: 0.7570167824, alpha: 1),#colorLiteral(red: 0, green: 0.4772562545, blue: 1, alpha: 1)].map({return $0.cgColor})
      gradientLayer.startPoint = CGPoint(x: 0, y: 0.5)
      gradientLayer.endPoint = CGPoint(x: 1, y: 0.5)
      gradientLayer.frame = self.frame.insetBy(dx: margin, dy: margin)
      gradientLayer.zPosition = 2
      gradientLayer.name = &quot;gradientLayer&quot;
      gradientLayer.contentsScale = (NSScreen.main()?.backingScaleFactor)!
      self.layer?.addSublayer(gradientLayer)
   }
}
</code></pre>
<p>At some point I want to get a NSImage (or CGImage) from <em>CALayer</em>s.
I found some samples around the Internet and turned them into this:</p>
<pre><code>extension CALayer {

func getBitmapImage() -&gt; NSImage {
    
    let btmpImgRep = NSBitmapImageRep(bitmapDataPlanes: nil, pixelsWide: Int(self.frame.width), pixelsHigh: Int(self.frame.height), bitsPerSample: 8, samplesPerPixel: 4, hasAlpha: true, isPlanar: false, colorSpaceName: NSDeviceRGBColorSpace, bytesPerRow: 0, bitsPerPixel: 0)
    
    let  image: NSImage = NSImage(size: self.frame.size)
    image.lockFocus()
    let ctx = NSGraphicsContext(bitmapImageRep: btmpImgRep!)
    let cgCtxt = ctx!.cgContext
    
    self.render(in: cgCtxt)
    cgCtxt.draw(layer: CGLayer, in: CGRect)
    
    image.unlockFocus()
    return image
  }
}
</code></pre>
<p>The first problem is that <em><strong>draw(layer: CGLayer, in: CGRect)</strong></em> method expects a CGLayer but not CALayer.</p>
<p>Secondly, I don't know if the code I ended up with will eventually render my layer or I'm doing something wrong.</p>
<p>Thanks for any help.</p>
<hr />
<p><strong>Edited:</strong>
Solution to get a CGImage from CALayer.</p>
<pre><code>extension CALayer {

func getBitmapImage() -&gt; NSImage {
    
    let btmpImgRep =
        NSBitmapImageRep(bitmapDataPlanes: nil, pixelsWide: Int(self.frame.width), pixelsHigh: Int(self.frame.height), bitsPerSample: 8, samplesPerPixel: 4, hasAlpha: true, isPlanar: false, colorSpaceName: NSDeviceRGBColorSpace, bytesPerRow: 0, bitsPerPixel: 32)

    let ctx = NSGraphicsContext(bitmapImageRep: btmpImgRep!)
    let cgContext = ctx!.cgContext
    
    self.render(in: cgContext)
    
    let cgImage = cgContext.makeImage()

    let nsimage = NSImage(cgImage: cgImage!, size: CGSize(width: self.frame.width, height: self.frame.height))

        return nsimage    
  }
}
</code></pre>
<p>How to get NSImage from NSView is in the answer below.</p>
<p><em>P.S. I don't know much about NSBitmapImageRep properties, so this part might be wrong.</em></p>