使用vImage仅提取一个通道

时间:2018-08-01 15:05:09

标签: swift image-processing accelerate-framework vimage

我目前在使用vImage框架时遇到问题。我试图从BGRA缓冲区中提取Alpha通道,但是即使对于某些图像来说效果很好,但是对于大于1040 * 1040px的图像,我的代码开始给我不一致的结果。现在,我有以下代码:

func processImage(_ image: UIImage) {
var cgImage = image.cgImage!
var sourceBuffer = vImage_Buffer()
var error = kvImageNoError
let unmanagedColorSpace: Unmanaged<CGColorSpace> = Unmanaged.passRetained(CGColorSpaceCreateDeviceRGB())
var format = vImage_CGImageFormat(bitsPerComponent: 8, bitsPerPixel: 32, colorSpace: unmanagedColorSpace, bitmapInfo: CGBitmapInfo(rawValue: (CGBitmapInfo.RawValue(CGImageAlphaInfo.premultipliedFirst.rawValue) | (CGBitmapInfo.byteOrder32Little.rawValue))), version: 0, decode: nil, renderingIntent: CGColorRenderingIntent.defaultIntent)
error = vImageBuffer_InitWithCGImage(&sourceBuffer, &format,nil,cgImage, vImage_Flags(kvImageNoFlags))
guard error == kvImageNoError else {
    fatalError("Error in vImageBuffer_InitWithCGImage: \(error)")
}

let count = Int(sourceBuffer.height * sourceBuffer.width)
let intStride = MemoryLayout<Int32>.stride
let byteCount = count * intStride

let rawPointer = UnsafeMutableRawPointer.allocate(byteCount: byteCount / 4, alignment: MemoryLayout<UInt8>.alignment)
var alphaBuffer = vImage_Buffer(data: rawPointer, height: sourceBuffer.height, width: sourceBuffer.width, rowBytes: sourceBuffer.rowBytes / 4)
alphaBuffer.data = sourceBuffer.data
guard error == kvImageNoError else {
    fatalError("Error in vImageBuffer_Init: \(error)")
}

error = vImageExtractChannel_ARGB8888(&sourceBuffer, &alphaBuffer, 3, vImage_Flags(kvImageNoFlags))
guard error == kvImageNoError else {
    fatalError("Error in vImageExtractChannel: \(error)")
}

var bufferPointer = UnsafeRawBufferPointer(start: alphaBuffer.data, count: byteCount / 4)
print(bufferPointer.enumerated().contains { $1 == 0 })

defer {
    unmanagedColorSpace.release()
    free(sourceBuffer.data)
}
}

我首先将图像转换为类似于vImage doc的vImage_Buffer(正在工作),然后创建一个符合说明的新缓冲区,使其成为extractChannel方法的目的地:< / p>

 @param dest
 A valid pointer to a vImage_Buffer struct which describes a 8-bit per component, one channel buffer.
 The buffer pointed to by dest should be allocated by you. It will be overwritten with one of the
 channels.  This function does work in place, so long as the rowBytes is the same for src and dest
 images and the start address also matches.

最后,我只是创建一个新的缓冲区指针来检查alpha缓冲区中包含的字节。

当我用1040 * 1040像素的全黑图像调用此函数时,它告诉我没有一个像素与255不同,这是预期的,但是如果它是1041 ** 1041,我的代码开始告诉我某些像素的alpha值为零。

我不明白为什么使用大于此特定大小的图像后,我的功能为什么会开始失败...您能帮我吗?

0 个答案:

没有答案