我有一个 .r32Float 像素格式的 MTLTexture,其值在 0 - 1 范围内。
将该纹理转换为 8 位或 16 位 NSBitmapImageRep 的最佳方法是什么?
想必您希望图像处于灰度色彩空间。对于 vImage 来说,这很简单,但也很冗长:
let width = texture.width
let height = texture.height
let sourceRowBytes = width * MemoryLayout<Float>.size
let floatValues = UnsafeMutablePointer<Float>.allocate(capacity: width * height)
defer {
floatValues.deallocate()
}
texture.getBytes(floatValues,
bytesPerRow: sourceRowBytes,
from: MTLRegionMake2D(0, 0, width, height),
mipmapLevel: 0)
var sourceBuffer = vImage_Buffer(data: floatValues,
height: vImagePixelCount(height),
width: vImagePixelCount(width),
rowBytes: sourceRowBytes)
let destRowBytes = width
let byteValues = malloc(width * height)!
var destBuffer = vImage_Buffer(data: byteValues,
height: vImagePixelCount(height),
width: vImagePixelCount(width),
rowBytes: destRowBytes)
vImageConvert_PlanarFtoPlanar8(&sourceBuffer, &destBuffer, 1.0, 0.0, vImage_Flags(kvImageNoFlags))
let bytesPtr = byteValues.assumingMemoryBound(to: UInt8.self)
let provider = CGDataProvider(data: CFDataCreateWithBytesNoCopy(kCFAllocatorDefault,
bytesPtr,
width * height,
kCFAllocatorDefault))!
let colorSpace = CGColorSpace(name: CGColorSpace.linearGray)!
let bitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.none.rawValue)
let image = CGImage(width: width,
height: height,
bitsPerComponent: 8,
bitsPerPixel: 8,
bytesPerRow: destRowBytes,
space: colorSpace,
bitmapInfo: bitmapInfo,
provider: provider,
decode: nil,
shouldInterpolate: false,
intent: .defaultIntent)!
let imageRep = NSBitmapImageRep(cgImage: image)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
686 次 |
| 最近记录: |