CIColor和CIFIlter:如何根据给定图像调整图像颜色

时间:2016-01-31 13:15:17

标签: swift2 cifilter

我想用另一张图片替换部分图片。在这个过程中,我希望粘贴的图像看起来类似于它在原始图像中替换的部分,并认为我需要调整粘贴图像的颜色。

怎么做? CIFilter应该使用什么潜力?快速欢迎的例子。

在您看来,CIColorMatrix可能会有所帮助,但在这种情况下,如何从原始图像部分获取​​颜色矩阵?

1 个答案:

答案 0 :(得分:2)

您需要直方图规范。此操作获取一个图像的直方图并将其应用于另一个图像。遗憾的是,CoreImage不包含直方图操作,因此您需要查看vImage的Metal Performance Shaders。我会快速为你运行vImage(taken from my blog

enter image description here

重新创建上述示例的第一步是计算直方图。我们将使用my previous post中描述的相同技术将提供的CGImage转换为vImage缓冲区。但是这一次,我们没有填充目标图像,我们正在填充四个无符号整数数组,这些整数将包含四个颜色通道(红色,绿色,蓝色和alpha)中每一个的直方图值。

vImage的API显示其C根并计算inBuffer的直方图,我们初始化四个数组,创建指向这些数组的指针并创建指向这些指针数组的指针:

let alpha = [UInt](count: 256, repeatedValue: 0)
let red = [UInt](count: 256, repeatedValue: 0)
let green = [UInt](count: 256, repeatedValue: 0)
let blue = [UInt](count: 256, repeatedValue: 0)

let alphaPtr = UnsafeMutablePointer<vImagePixelCount>(alpha)
let redPtr = UnsafeMutablePointer<vImagePixelCount>(red)
let greenPtr = UnsafeMutablePointer<vImagePixelCount>(green)
let bluePtr = UnsafeMutablePointer<vImagePixelCount>(blue)

let rgba = [alphaPtr, redPtr, greenPtr, bluePtr]

let histogram = UnsafeMutablePointer<UnsafeMutablePointer<vImagePixelCount>>(rgba)

直方图对象与源图像一起传递给vImageHistogramCalculation_ARGB8888(_:_:_:)

vImageHistogramCalculation_ARGB8888(&inBuffer, histogram, UInt32(kvImageNoFlags))

现在,原始数组(alpha,red,green和blue)填充了直方图数据。

直方图规范

鉴于直方图数据,我们现在需要针对另一个图像(在我们的例子中为日落)指定它。在我的例子中,我将这两个步骤分成两个函数,我的规范函数需要一个形式的直方图元组:

histogram: (alpha: [UInt], red: [UInt], green: [UInt], blue: [UInt])

vImage规范函数vImageHistogramSpecification_ARGB888(_:_:_:_:)需要一个不安全的可变指针,指向每个通道的每个存储桶的像素计数的不安全指针。以下代码准备直方图以传递到vImage(vImagePixelCountUint的类型别名):

let alphaPtr = UnsafePointer<vImagePixelCount>(histogram.alpha)
let redPtr = UnsafePointer<vImagePixelCount>(histogram.red)
let greenPtr = UnsafePointer<vImagePixelCount>(histogram.green)
let bluePtr = UnsafePointer<vImagePixelCount>(histogram.blue)

let rgba = UnsafeMutablePointer<UnsafePointer<vImagePixelCount>>([alphaPtr, redPtr, greenPtr, bluePtr])

使用previous post中的inBuffer和outBuffer技术,我们现在可以指定源图像的直方图并填充vImage缓冲区:

vImageHistogramSpecification_ARGB8888(&inBuffer, &outBuffer, rgba, UInt32(kvImageNoFlags))