我正在使用 CGBitmapContextCreate
和 kCGImageAlphaPremultipliedFirst
选项创建位图上下文。
我制作了一张 5 x 5 的测试图像,其中包含一些主要颜色(纯红色、绿色、蓝色、白色、黑色)、一些混合颜色(即紫色)以及一些 alpha 变化。每次alpha分量不为255时,颜色值都是错误的。
我发现我可以在执行以下操作时重新计算颜色:
almostCorrectRed = wrongRed * (255 / alphaValue);
almostCorrectGreen = wrongGreen * (255 / alphaValue);
almostCorrectBlue = wrongBlue * (255 / alphaValue);
但问题是,我的计算有时会偏差 3 甚至更多。例如,对于绿色,我得到的值是 242 而不是 245,而且我 100% 确定它一定正好是 245。Alpha 是 128。
然后,对于完全相同的颜色,只是在 PNG 位图中具有不同的 alpha 不透明度,我得到了 alpha = 255 和 green = 245,这是应该的。
如果 alpha 为 0,则红色、绿色和蓝色也为 0。这里所有数据都丢失了,我无法确定像素的颜色。
我如何才能避免或完全取消此 alpha 预乘,以便我可以根据在 Photoshop 中创建图像时的真实 R G B 像素值修改图像中的像素?如何恢复 R、G、B 和 A 的原始值?
背景信息(这个问题可能不需要):
我正在做的是:我获取一个 UIImage,将其绘制到位图上下文中,以便对其执行一些简单的图像处理算法,根据每个像素之前的颜色改变每个像素的颜色.没什么特别的。但是我的代码需要真实的颜色。当一个像素是透明的(意味着它的 alpha 小于 255)时,我的算法不应该关心这个,它应该只根据需要修改 R、G、B,而 Alpha 保持不变。有时它也会向上或向下移动 alpha。但我认为它们是两个独立的事物。 Alpha 控制透明度,而 R G B 控制颜色。
最佳答案
这是整数类型预乘的一个基本问题:
- 245 * (128/255) = 122.98
- 122.98 截断为整数 = 122
- 122 * (255/128) = 243.046875
我不确定为什么你得到的是 242 而不是 243,但无论哪种方式,这个问题仍然存在,而且 alpha 越低,情况就越糟。
解决方案是使用floating-point components反而。 Quartz 2D 编程指南给出了 the full details of the format you'll need to use .
要点:您需要在创建原始图像时使用 float (而且我认为甚至不可能将这样的图像保存为 PNG;您可能必须使用 TIFF)。已经以整数类型预乘的图像已经失去了精度;无法取回。
零 alpha 情况是这种情况的极端版本,其程度甚至连 float 都无法帮助您。零 (alpha) 的任何时间都是零,并且无法从该点恢复原始的未预乘值。
关于iphone - 如何在没有预乘 alpha 的情况下获得真正的 RGBA 或 ARGB 颜色值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6396139/