3

实际上,我认为有一种简单的方法可以实现这一目标。我需要的是纯 alpha 值信息。为了进行测试,我有一个 50 x 55 像素的 PNG,其中每条边上都有一个 5x5 像素的矩形是完全透明的。在这些区域中,alpha 必须为 0。其他任何地方都必须为 255。我非常确定我的 PNG 是正确创建的,而且它看起来也正确。

请告诉我这在理论上是否正确:我创建了一个只有 alpha 通道而没有其他内容的 CGImageRef。这是使用 CGBitmapContextCreate 和 kCGImageAlphaOnly 作为参数完成的。CGBitmapContextGetBitsPerPixel(context) 返回 1,因此它表明我确实每个像素只有一个组件:所需的 alpha 值。我一直在阅读 CGBitmapContextCreate 将处理从给定图像到新创建的上下文的所有转换。我的图像以前是具有透明度的 PNG-24,但来自 Xcode 的 pngcrunch 似乎以某种方式转换它们。

所以,就理论上而言:此时我是否有机会获得正确的、未预乘的 alpha?我得到的值似乎几乎匹配,但在一个 5x5 的大透明正方形中,我得到的值是 19、197、210、0、0、0、98 等。如果它们是真的,我将不得不从图像中看到一些东西。图像本身是纯蓝色的。

4

3 回答 3

8

预乘不影响 Alpha 通道,它会影响颜色通道。

光栅合成的公式(将一个光栅图像放在另一个上)是:

dst.r = src.r * src.a + dst.r * (1.0 - src.a);
dst.g = src.g * src.a + dst.g * (1.0 - src.a);
dst.b = src.b * src.a + dst.b * (1.0 - src.a);

预乘去掉第一个乘法表达式:

dst.r = src.r′ + dst.r * (1.0 - src.a);
dst.g = src.g′ + dst.g * (1.0 - src.a);
dst.b = src.b′ + dst.b * (1.0 - src.a);

这是因为源颜色分量已经乘以 alpha 分量——因此得名“预乘”。现在不需要将它们相乘,因为它已经有了结果。

未预乘的阿尔法

alpha 分量本身永远不会被预乘:你会将它乘以什么?颜色分量由alpha预乘。

于 2009-05-16T01:19:48.020 回答
6

由于预乘颜色值很简单:

r = (r * a) / 255;
g = (g * a) / 255;
b = (b * a) / 255;

得到逆将是:

if (a > 0) {
    r = (r * 255) / a;
    g = (g * 255) / a;
    b = (b * 255) / a;
}
于 2009-05-16T01:26:55.007 回答
1

这个公式是不正确的。目标是找到未多路复用的 (r, g, b),后者将导致相同的多路复用值(但是,不可能找到原始的 r、g、b 值。

但是,使用上面的公式,我们可以找到以下示例

alpha = 100
r_premulti = 1

重构的 r = 2;

后面如果这个 r 再次被多路复用,我们会发现 2 * 100 / 255 = 0 但我们想要 r_premulti == 1 !

正确的公式需要四舍五入。r 分量的示例:

reconstruced r = ceiling(r_premulti * 255 / alpha)
于 2013-03-26T16:43:50.017 回答