使用vImageMatrixMultiply_ARGB8888将颜色矩阵滤镜应用于UIImage,就像CIColorMatrix一样

问题描述 投票:0回答:1

我正在尝试构建快速函数,以使用Accellerate框架的vImageMatrixMultiply_ARGB8888将色彩矩阵滤镜应用于图像。我以前可以使用CIFilter CIColorMatrix。

将颜色矩阵应用于图像
     let ciimage = CIImage(image: image)!
     let colorMatrix = CIFilter(name: "CIColorMatrix")!
     colorMatrix.setDefaults()
     colorMatrix.setValue(ciimage, forKey: "inputImage")
     colorMatrix.setValue(CIVector(x: 1.9692307692307693, y: 0, z: 0, w: 0), forKey: "inputRVector")
     colorMatrix.setValue(CIVector(x: 0, y: 2.226086956521739, z: 0, w: 0), forKey: "inputGVector")
     colorMatrix.setValue(CIVector(x: 0, y: 0, z: 2.585858585858586, w: 0), forKey: "inputBVector")
     colorMatrix.setValue(CIVector(x: 0, y: 0, z: 0, w: 1), forKey: "inputAVector")
     return UIImage(ciImage: colorMatrix.outputImage!)

vImageMatrixMultiply_ARGB8888]中使用的RotatioMatrix使用CIFilter相同值输入向量。

rotationMatrix = [1.9692307692307693, 0, 0, 0
                  0, 2.226086956521739, 0, 0,
                  0, 0, 2.585858585858586, 0,
                  0, 0, 0, 1].map {
                     return Int16(Float($0) * Float(divisor)) // divisor = 256
                  }

下面的代码不会产生与上面的CIFilter相同的结果。

private func rgbAdjustmentWithMatrix(image sourceImage: UIImage, rotationMatrix: [Int16]) -> UIImage? {

    guard
        let cgImage = sourceImage.cgImage,
        let sourceImageFormat = vImage_CGImageFormat(cgImage: cgImage),
        let rgbDestinationImageFormat = vImage_CGImageFormat(
            bitsPerComponent: 8,
            bitsPerPixel: 32,
            colorSpace: CGColorSpaceCreateDeviceRGB(),
            bitmapInfo: CGBitmapInfo(rawValue: CGImageAlphaInfo.first.rawValue),
            renderingIntent: .defaultIntent) else {
                print("Unable to initialize cgImage or colorSpace.")
                return nil
    }

    guard
        let sourceBuffer = try? vImage_Buffer(cgImage: cgImage),
        var rgbDestinationBuffer = try? vImage_Buffer(width: Int(sourceBuffer.width),
            height: Int(sourceBuffer.height),
            bitsPerPixel: rgbDestinationImageFormat.bitsPerPixel) else {
                print("Unable to initialize source buffer or destination buffer.")
                return nil
    }

    defer {
        sourceBuffer.free()
        rgbDestinationBuffer.free()
    }

    do {
        let toRgbConverter = try vImageConverter.make(sourceFormat: sourceImageFormat, destinationFormat: rgbDestinationImageFormat)
            try toRgbConverter.convert(source: sourceBuffer, destination: &rgbDestinationBuffer)
    } catch {
        print("Unable to initialize converter or unable to convert.")
        return nil
    }

    guard var resultBuffer = try? vImage_Buffer(width: Int(sourceBuffer.width),
            height: Int(sourceBuffer.height),
            bitsPerPixel: rgbDestinationImageFormat.bitsPerPixel) else {
                print("Unable to initialize result buffer.")
                return nil
    }

    defer {
        resultBuffer.free()
    }
    var error: vImage_Error

    let divisor: Int32 = 256

    let preBias = [Int16](repeating: -256, count: 4)
    let postBias = [Int32](repeating: 256 * divisor, count: 4)

    error = vImageMatrixMultiply_ARGB8888(&rgbDestinationBuffer,
                                  &resultBuffer,
                                  rotationMatrix,
                                  divisor,
                                  preBias,
                                  postBias,
                                  0)
    guard error == kvImageNoError else { return nil }

    if let cgImage = try? resultBuffer.createCGImage(format: rgbDestinationImageFormat) {
        return UIImage(cgImage: cgImage)
    } else {
        return nil
    } 

}

可能是色彩空间问题?还是vImageMatrixMultiply_ARGB8888输入矩阵与CIFilter输入矩阵不同?

我正在尝试使用Accellerate框架的vImageMatrixMultiply_ARGB8888构建快速函数以将颜色矩阵滤镜应用于图像。我以前能够将颜色矩阵应用于图像...

swift cifilter accelerate-framework
1个回答
0
投票

查看您的代码和输出图像,我相信您将红色和蓝色系数颠倒了。如果是这样,您可以像这样填充vImage矩阵:

© www.soinside.com 2019 - 2024. All rights reserved.