1

我尝试了很多技术,例如使用 CIImage 或将数据复制到 uint_32ts 的缓冲区中,但它们都有自己的问题。到目前为止我发现的最简单的是:


extension MTLTexture {
    
    func toImage() -> NSImage? {
        
        assert (pixelFormat == .rgba32Float)
        let rowByteCount = width * 16
        let bytes = UnsafeMutablePointer<Float>.allocate(capacity: width * height * 4)
        defer {
            bytes.deallocate()
        }
        getBytes(bytes,
                 bytesPerRow: rowByteCount,
                 from: MTLRegion(origin: MTLOrigin(x: 0, y: 0, z: 0),
                                 size: MTLSize(width: width, height: height, depth: 1)),
                 mipmapLevel: 0)
        let context = CGContext(data: bytes,
                                width: width,
                                height: height,
                                bitsPerComponent: 32,
                                bytesPerRow: rowByteCount,
                                space: CGColorSpaceCreateDeviceRGB(),
                                bitmapInfo: CGImageAlphaInfo.premultipliedLast.rawValue | CGBitmapInfo.floatComponents.rawValue)
        guard let cgImage = context?.makeImage() else { print("Failed making cgImage"); return nil }
    
        return NSImage(cgImage: cgImage, size: NSSize(width: width, height: height))
    }
    
}

这将创建正确大小的图像,但它是完全透明的。有时使用预览放大时,图像中某些特征的轮廓会闪烁,但一旦图像渲染,它就会消失。我确保同步图像,并确保bytes缓冲区具有非零值。我也尝试过使用 s 的缓冲区SIMD4<Float>而不是Floats,但它产生了相同的结果。

4

0 回答 0