jj200789
jj200789

Reputation: 41

vImageMatrixMultiply_ARGB8888ToPlanar8 is not work while build release mode iOS application

I am developing an image processing application and try to use the vImage. It works great and gets right result in debug mode. However, it always returns a black image or throws an error in release mode.

I have already tried the official example which also gets a black image when I build it in release mode.

func uiImageToBuffer(image: UIImage) -> vImage_Buffer? {
    guard let cgImage = image.cgImage,
          var format = cgImageFormat(of: image)
    else { return nil }

    var buffer = vImage_Buffer()
    let error = vImageBuffer_InitWithCGImage(&buffer, &format, nil, cgImage, vImage_Flags(kvImageNoFlags))
    if error == kvImageNoError {
        return buffer
    } else {
        return nil
    }
}


func grayBuffer(_ buffer: vImage_Buffer) -> vImage_Buffer {
    var _buffer = buffer
    var destinationBuffer = vImage_Buffer()
    vImageBuffer_Init(&destinationBuffer, buffer.height, buffer.width, 8, vImage_Flags(kvImageNoFlags))

    let redCoefficient: Float = 0.2126
    let greenCoefficient: Float = 0.7152
    let blueCoefficient: Float = 0.0722

    let divisor = Float(0x1000)

    var coefficientsMatrix = [
        Int16(redCoefficient * divisor),
        Int16(greenCoefficient * divisor),
        Int16(blueCoefficient * divisor)
    ]

    var preBias: Int16 = 0
    let postBias: Int32 = 0

    vImageMatrixMultiply_ARGB8888ToPlanar8(&_buffer, &destinationBuffer,
                                           &coefficientsMatrix, 0x1000, &preBias, postBias, vImage_Flags(kvImageNoFlags))

    return destinationBuffer
}

func main() {
    guard let imageBuffer = uiImageToBuffer(image: image),
          var grayBuffer = grayBuffer(buffer) 
    else { return }

    var monoFormat = vImage_CGImageFormat(bitsPerComponent: 8, bitsPerPixel: 8,
                                  colorSpace: Unmanaged.passRetained(CGColorSpaceCreateDeviceGray()),
                                  bitmapInfo: CGBitmapInfo(rawValue: CGImageAlphaInfo.none.rawValue),
                                  version: 0, decode: nil, renderingIntent: .defaultIntent)

    let cgImage = vImageCreateCGImageFromBuffer(&grayBuffer, &monoFormat, nil, nil, vImage_Flags(kvImageNoFlags), nil)
    if let cgImage = cgImage {
        imageView.image = UIImage(cgImage: cgImage.takeRetainedValue())
    }
    free(imageBuffer.data)
    free(grayBuffer.data)
}

Upvotes: 1

Views: 288

Answers (1)

Flex Monkey
Flex Monkey

Reputation: 3643

The pre-bias should be a vector of four elements. Try this:

let preBias: [Int16] = [0, 0, 0, 0]
let postBias: Int32 = 0

vImageMatrixMultiply_ARGB8888ToPlanar8(&_buffer, 
                                       destinationBuffer,
                                       &coefficientsMatrix, 
                                       0x1000, 
                                       preBias, 
                                       postBias, 
                                       vImage_Flags(kvImageNoFlags))

Upvotes: 0

Related Questions