【发布时间】:2020-08-12 09:06:09
【问题描述】:
我正在尝试使用 Accelerate 框架的 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 输入矩阵不同?
【问题讨论】:
-
结果如何?
-
这是我将所述矩阵[1.1592593003986569,1.4509703520780686,-0.887754951702713,0.0,0.0,1.2018779342723005,0.0,0.0,0.0,0.0,1.2190476190476192,0.0,0.0,0.0,0.0,1.0]
标签: swift cifilter accelerate-framework