我将使用 Accelerate 框架将矩阵应用于 CGImage。
首先,我将 CGImage 转换为 vImage_Buffer,
let bitmapInfo: CGBitmapInfo = [ .floatComponents,
CGBitmapInfo( rawValue: CGImageAlphaInfo.none.rawValue ),
.byteOrder32Little ]
var format = vImage_CGImageFormat( bitsPerComponent: 32,
bitsPerPixel: 32 * 3,
colorSpace: nil,
bitmapInfo: FloatBitmapInfo,
version: 0,
decode: nil,
renderingIntent: .defaultIntent )
var inputBuffer = vImage_Buffer()
vImageBuffer_InitWithCGImage( &inputBuffer,
&format,
nil,
aCGImage, // input CGImage
UInt32( kvImageNoFlags ) )
然后尝试应用 vImageMatrixMultiply。
vImageMatrixMultiply_PlanarF( &inputBuffer, // srcs
&outputBuffer, // dests
3, // src_planes
3, // dest_planes
aMatrix, // applying matrix
&preBias, // pre_bias
&postBias, // post_bias
UInt32( kvImageNoFlags ) )
但是 vImageMatrixMultiply 不接受 vImage_Buffer 作为 srcs 和 dests 参数,并且我收到一个编译错误,描述:
Cannot convert value of type "vImage_Buffer" to expected argument type "UnsafePointer< vImage_Buffer >?"
我搜索了有关将“vImage_Buffer”转换为“UnsafePointer< vImage_Buffer >?”的信息但还没有找到任何答案。
所以我想知道如何将“vImage_Buffer”转换为“UnsafePointer< vImage_Buffer >?”,或者如何直接创建“UnsafePointer< vImage_Buffer >?”来自 CGImage,或任何其他适当使用 vImageMatrixMultiply 的方法。
最佳答案
我没有使用过vImageMatrixMultiply_PlanarF
,但根据 header 文档和函数签名,您需要将指针传递给多个 vImage_Buffer
s 代表前两个参数,srcs
和dests
.
当需要通过 UnsafeMutablePointer<T>
传递多个值时,通常声明一个变量 [T]
,并将其作为 inout 参数传递。
就您而言T
=UnsafePointer<vImage_Buffer>?
,所以你需要声明一个 [UnsafePointer<vImage_Buffer>?]
类型的变量。
并且数组中包含的每个指针都需要指向一个适当准备的vImage_Buffer
.
已更新
此答案中的旧代码使用 with...
方法不当。请尝试使用更新的代码。
因此,您可能需要编写如下内容:
//Prepare 3 vImage_Buffers for source planes
//(vImageConvert_RGBFFFtoPlanarF)
//You are responsible for filling out the height, width, and rowBytes fields of this structure, and for allocating a data buffer of the appropriate size.
let inputBuffers: [vImage_Buffer] = (0...2).map {_ in
var imageBuf = vImage_Buffer()
imageBuf.width = inputBuffer.width
imageBuf.height = inputBuffer.height
imageBuf.rowBytes = Int(imageBuf.width) * MemoryLayout<Float>.size
imageBuf.data = malloc(imageBuf.rowBytes * Int(imageBuf.height))
return imageBuf
}
//Prepare 3 vImage_Buffers for destination planes
//(vImageMatrixMultiply_PlanarF)
//You are responsible for filling out the height, width, and rowBytes fields of these structures, and for allocating data buffers of the appropriate size.
let outputBuffers: [vImage_Buffer] = (0...2).map {_ in
var imageBuf = vImage_Buffer()
imageBuf.width = inputBuffer.width
imageBuf.height = inputBuffer.height
imageBuf.rowBytes = Int(imageBuf.width) * MemoryLayout<Float>.size
imageBuf.data = malloc(imageBuf.rowBytes * Int(imageBuf.height))
return imageBuf
}
//`aMatrix` needs to hold `src_planes`x`dest_planes` elements
let aMatrix: [Float] = [0.5, 0.25, 0.25, 0.25, 0.5, 0.25, 0.25, 0.25, 0.5]
var preBias: Float = 0.0
var postBias: Float = 0.0
//You need to use pointers or BufferPointers inside the closure, should not take them out of the closure
inputBuffers.withUnsafeBufferPointer {inputBuffersBP in
outputBuffers.withUnsafeBufferPointer {outputBuffersBP in
//Prepare pointer array pointing each vImage_Buffer
var inputBufferPointers: [UnsafePointer<vImage_Buffer>?] =
inputBuffers.withUnsafeBufferPointer {inputBuffersBP in
(0...2).map{inputBuffersBP.baseAddress! + $0}
}
//If you want to use PlanarF format, you need to split RGB into distict vImage_Buffers
vImageConvert_RGBFFFtoPlanarF(
&inputBuffer,
inputBufferPointers[0]!,
inputBufferPointers[1]!,
inputBufferPointers[2]!,
UInt32(kvImageNoFlags)
)
//Prepare pointer array pointing each vImage_Buffer
var outputBufferPointers: [UnsafePointer<vImage_Buffer>?] =
outputBuffers.withUnsafeBufferPointer {outputBuffersBP in
(0...2).map{outputBuffersBP.baseAddress! + $0}
}
//All these things prepared properly, you can call `vImageMatrixMultiply_PlanarF` like this...
vImageMatrixMultiply_PlanarF(
&inputBufferPointers, // srcs
&outputBufferPointers, // dests
3, // src_planes
3, // dest_planes
aMatrix, // applying matrix
&preBias, // pre_bias
&postBias, // post_bias
UInt32(kvImageNoFlags)
)
}
}
关于swift - 如何在 Swift 3 中使用 vImageMatrixMultiply?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39928524/