0

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 引数として受け入れず、次のようなコンパイル エラーが発生しました。

タイプ「vImage_Buffer」の値を予期される引数タイプ「UnsafePointer< vImage_Buffer >?」に変換できません。

「vImage_Buffer」を「UnsafePointer< vImage_Buffer >?」に変換する方法について調べてみました。しかし、答えは見つかりませんでした。

そこで、「vImage_Buffer」を「UnsafePointer< vImage_Buffer >?」に変換する方法、または「UnsafePointer< vImage_Buffer >?」を直接作成する方法を知りたいです。CGImage から、または vImageMatrixMultiply を適切に使用するその他の方法。

4

1 に答える 1

0

は使用していませんvImageMatrixMultiply_PlanarFが、ヘッダー ドキュメントと関数のシグネチャによるとvImage_Buffer、最初の 2 つのパラメーターsrcsdests.

を介して複数の値を渡す必要がある場合UnsafeMutablePointer<T>、通常は の変数を宣言し、[T]それを inout 引数として渡します。

あなたの場合はT= なのでUnsafePointer<vImage_Buffer>?、 type の変数を宣言する必要があります[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)
            )
        }
    }
于 2016-10-08T08:46:12.000 に答える