CIColorMatrix 数学没有意义

CIColorMatrix math doesn't make sense

我正在尝试在 iOS 上的 Swift 中使用 CIColorMatrix,但我得到的结果与我对它应该如何工作的理解不符。

documentation定义为:

s.r = dot(s, redVector)
s.g = dot(s, greenVector)
s.b = dot(s, blueVector)
s.a = dot(s, alphaVector)
s = s + bias

假设我有一个 RGBA 值 [255, 0, 0, 255](100% 红色)的输入像素。然后我将向量 [0.5, 0, 0, 0] 应用到红色通道。这不应该导致 127 的红色通道值吗?

(255*0.5)+(0*0)+(0*0)+(255*0) = 127.5

出于某种原因,使用这些值,CIColorMatrix 为我提供了 187 的值。这不是他们说的dot()的定义吗?

这是一个代码片段(输入图像全是红色)。

// Before this, the RGB values are [255, 0, 0]
let vec = CIVector(x: 0.5, y: 0, z: 0, w: 0)
let filter = CIFilter(name: "CIColorMatrix")
filter!.setDefaults()
// Default bias is [0,0,0,0] (explicitly setting it as such doesn't change the result).
filter!.setValue(myImage, forKey: kCIInputImageKey)
filter!.setValue(vec, forKey: "inputRVector")
// After this, the RGB values are [187, 0, 0]

我在这里遗漏或误解了什么?

所有 Core Image 滤镜都以执行它们的 CIContext 的工作颜色 space 运行。过滤器内核也适用于 alpha 未预乘像素值,而过滤器输出是预乘的。如果您看到的结果不是您所期望的,请检查您的工作和输出颜色 space 是否按照您的需要进行了配置,并确保您没有对 alpha 预乘做任何有趣的事情。

CIColorMatrix 滤镜的另一个注意事项是它的参数应用于未预乘的颜色值。所以实际上内核的行为就像它的代码看起来像:

s = unpremultiply(s)
s.r = dot(s, redVector)
s.g = dot(s, greenVector)
s.b = dot(s, blueVector)
s.a = dot(s, alphaVector)
s = s + bias
s = premultiply(s)

如果您的颜色不透明(例如 [255, 0, 0, 255]),则 unpremultiply/premultiply 无效。