1.如果您使用MTKView: let texture = view.currentDrawable!.texture 2.如果您不使用MTKView这就是我要做的-我将拥有一个属性,该属性将最后一个可绘制的内容显示在屏幕上:let lastDrawableDisplayed: CAMetalDrawable?然后在屏幕上显示可绘制对象时,我将对其进行更新:let commandBuffer = commandQueue.commandBuffer()commandBuffer.addCompletedHandler({ (buffer:MTLCommandBuffer!) -> Void in self.lastDrawableDisplayed = drawable})现在,无论何时需要截图,您都可以像这样获得纹理:let texture = lastDrawableDisplayed.texture好吧,现在有了MTLTexture时,您可以将其转换为CGImage,然后转换为UIImage或NSImage.这是OS X游乐场(MetalKit.MTLTextureLoader不适用于iOS游乐场)的代码,在其中我将MTLTexture转换为CGImage为此,我在MTLTexture上做了一个小扩展.import Metalimport MetalKitimport Cocoalet device = MTLCreateSystemDefaultDevice()!let textureLoader = MTKTextureLoader(device: device)// PATH TO YOUR IMAGE FILElet path = "/Users/haawa799/Desktop/Metal_Snapshot.playground/Resources/q.jpg"let data = NSData(contentsOfFile: path)!let texture = try! textureLoader.newTextureWithData(data, options: nil)extension MTLTexture { func bytes() -> UnsafeMutablePointer<Void> { let width = self.width let height = self.height let rowBytes = self.width * 4 let p = malloc(width * height * 4) self.getBytes(p, bytesPerRow: rowBytes, fromRegion: MTLRegionMake2D(0, 0, width, height), mipmapLevel: 0) return p } func toImage() -> CGImage? { let p = bytes() let pColorSpace = CGColorSpaceCreateDeviceRGB() let rawBitmapInfo = CGImageAlphaInfo.NoneSkipFirst.rawValue | CGBitmapInfo.ByteOrder32Little.rawValue let bitmapInfo:CGBitmapInfo = CGBitmapInfo(rawValue: rawBitmapInfo) let selftureSize = self.width * self.height * 4 let rowBytes = self.width * 4 let provider = CGDataProviderCreateWithData(nil, p, selftureSize, nil) let cgImageRef = CGImageCreate(self.width, self.height, 8, 32, rowBytes, pColorSpace, bitmapInfo, provider, nil, true, CGColorRenderingIntent.RenderingIntentDefault)! return cgImageRef }}if let imageRef = texture.toImage() { let image = NSImage(CGImage: imageRef, size: NSSize(width: texture.width, height: texture.height))I tried: let scale = UIScreen.mainScreen().scale UIGraphicsBeginImageContextWithOptions(metalLayer.bounds.size,false,scale) // metalLayer.renderInContext(UIGraphicsGetCurrentContext()!) // self.view.layer ... metalLayer.presentationLayer()!.renderInContext(UIGraphicsGetCurrentContext()!) let image = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext(); UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil)But the result is a empty screenshot. Any help would be nice!Please keep in mind that i want to take a snapshot of a CAMetalLayer 解决方案 To make a screenshot, you need to get MTLTextureof the frame buffer.1. If you use MTKView:let texture = view.currentDrawable!.texture2. If you don't use MTKViewHere's what I would do - I would have a property which holds last drawable presented to the screen:let lastDrawableDisplayed: CAMetalDrawable?And then when you present drawable to the screen, I would update it:let commandBuffer = commandQueue.commandBuffer()commandBuffer.addCompletedHandler({ (buffer:MTLCommandBuffer!) -> Void in self.lastDrawableDisplayed = drawable})Now you whenever you need to make a screenshot, you can get texture like this:let texture = lastDrawableDisplayed.textureOk, now when you have MTLTexture you can convert it to CGImage and then to UIImage or NSImage.Here's the code for OS X playground (MetalKit.MTLTextureLoader is not available for iOS playgrounds), in which I convert MTLTexture to CGImageI made a small extension over MTLTexture for this.import Metalimport MetalKitimport Cocoalet device = MTLCreateSystemDefaultDevice()!let textureLoader = MTKTextureLoader(device: device)// PATH TO YOUR IMAGE FILElet path = "/Users/haawa799/Desktop/Metal_Snapshot.playground/Resources/q.jpg"let data = NSData(contentsOfFile: path)!let texture = try! textureLoader.newTextureWithData(data, options: nil)extension MTLTexture { func bytes() -> UnsafeMutablePointer<Void> { let width = self.width let height = self.height let rowBytes = self.width * 4 let p = malloc(width * height * 4) self.getBytes(p, bytesPerRow: rowBytes, fromRegion: MTLRegionMake2D(0, 0, width, height), mipmapLevel: 0) return p } func toImage() -> CGImage? { let p = bytes() let pColorSpace = CGColorSpaceCreateDeviceRGB() let rawBitmapInfo = CGImageAlphaInfo.NoneSkipFirst.rawValue | CGBitmapInfo.ByteOrder32Little.rawValue let bitmapInfo:CGBitmapInfo = CGBitmapInfo(rawValue: rawBitmapInfo) let selftureSize = self.width * self.height * 4 let rowBytes = self.width * 4 let provider = CGDataProviderCreateWithData(nil, p, selftureSize, nil) let cgImageRef = CGImageCreate(self.width, self.height, 8, 32, rowBytes, pColorSpace, bitmapInfo, provider, nil, true, CGColorRenderingIntent.RenderingIntentDefault)! return cgImageRef }}if let imageRef = texture.toImage() { let image = NSImage(CGImage: imageRef, size: NSSize(width: texture.width, height: texture.height)) 这篇关于使用Metal快速拍摄当前屏幕快照的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云!