kCGImageAlphaPremultipliedFirst和kCGImageAlphaFirst

Tom*_*ulc 5 pixel bitmap objective-c quartz-graphics cgcontext

你能解释一下kCGImageAlphaPremultipliedFirst和之间的区别kCGImageAlphaFirst吗?Premultiplied在实践中意味着什么?

jus*_*tin 7

简而言之,预乘意味着当表示非不透明的像素时,α值也将影响像素的颜色分量值.

从Quartz 2D绘图指南:

对于具有alpha分量的位图,颜色分量是否已经乘以alpha值.预乘alpha描述了一种源颜色,其组件已经乘以alpha值.预乘通过消除每个颜色分量的额外乘法运算来加速图像的渲染.例如,在RGB颜色空间中,渲染具有预乘alpha的图像消除了图像中每个像素的三个乘法运算(红色倍α,绿倍alpha和蓝倍alpha).

BTW,Pre-Multiplied可能是API会强制您使用的,因为这是Quartz的偏好.幸运的是,转换并不可怕(有损OTOH ......).


最简单的解释方法是在float组件中使用范围[0...1].

如果我们的RGBA输入表示是:

typedef struct t_rgba { float r,g,b,a; } t_rgba;
const t_rgba rgba = { 0.5, 0.5, 0.5, 0.5 };
Run Code Online (Sandbox Code Playgroud)

然后预先乘以它:

t_rgba rgba_PreMul = rgba;
rgba_PreMul.r *= rgba_PreMul.a;
rgba_PreMul.g *= rgba_PreMul.a;
rgba_PreMul.b *= rgba_PreMul.a;
Run Code Online (Sandbox Code Playgroud)

然后去预乘它:

t_rgba rgba_DePreMul = rgba_PreMul;
if (0.0 < rgba_DePreMul.a && 1.0 > rgba_DePreMul.a) {
  const float ialpha = 1.0/rgba_DePreMul.a;
  rgba_DePreMul.r *= ialpha;
  rgba_DePreMul.g *= ialpha;
  rgba_DePreMul.b *= ialpha;
}
Run Code Online (Sandbox Code Playgroud)

你也可能想要一些饱和度.

现在这是基本形式,可以重新用于其他数字表示.请注意,这些转换是有损的.同样,注意不要传递预期常规位图的预乘位图,反之亦然.