4

我有一种预感,这以前已经做过,但我对此完全是外行,不知道如何开始提出正确的问题。所以我将描述我正在尝试做的事情......

我有一个未知的 ARGB 颜色。我只知道它的绝对 RGB 值显示在两种已知的不透明背景颜色上,例如黑色 0x000000 和白色 0xFFFFFF。所以,继续这个例子,如果我知道 ARGB 颜色在 0x000000 上显示时等效于 RGB 0x000080,并且我知道相同的 ARGB 颜色在 0xFFFFFF 上显示时等效于 RGB 0x7F7FFF,有没有办法计算原始 ARGB 颜色是?

或者这甚至可能吗?

4

2 回答 2

2

因此,您知道将 (a,r,g,b) 放在 (r1,g1,b1) 上会得到 (R1,G1,B1) 放在 (r2,g2,b2) 上会得到 (R2,G2 ,B2)。换句话说——顺便说一下,我将在这里工作的单位是从 0 到 1 的单位——你知道 (1-a)r1+ar=R1、(1-a)r2+ar=R2 等。取这两个并减去:你得到 (1-a)(r1-r2)=R1-R2,因此 a=1-(R1-R2)/(r1-r2)。一旦你知道了一个,你就可以解决其他所有问题。

您实际上应该计算从对所有三个 {R,G,B} 进行计算得到的 a 的值,并将它们平均或其他东西,以减少舍入误差的影响。事实上,我建议您采用 a = 1 - [(R1-R2)sign(r1-r2) + (G1-G2)sign(g1-g2) + (B1-B2)sign(b1-b2)] / (|r1-r2|+|g1-g2|+|b1-b2),这相当于对更可靠的颜色进行更高的加权。

现在你有,例如,r = (R1-(1-a)r1)/a = (R2-(1-a)r2)/a。如果 a、r、g、b 具有无限精度值,这两个值将相等,但当然在实践中它们可能会略有不同。平均它们:r = [(R1+R2)-(1-a)(r1+r2)]/2a。

如果您的 a 值恰好非常小,那么您将只能获得关于 r,g,b 的相当不可靠的信息。(在 a=0 的限制下,您根本不会获得任何信息,显然您对此无能为力。)您可能会获得 0..255 范围之外的数字,在这种情况下我不会认为你可以做得比剪裁更好。

这是您的特定示例的效果。(r1,g1,b1)=(0,0,0); (r2,g2,b2)=(255,255,255); (R1,G1,B1)=(0,0,128); (R2,G2,B2)=(127,127,255)。所以 a = 1 - [127+127+127]/[255+255+255] = 128/255,恰好是 a 的 256 个实际可能值之一。(如果不是,我们可能应该在这个阶段对其进行舍入。)

现在 r = (127-255*127/255)*255/256 = 0; 同样 g = 0; b = (383-255*127/255)*255/256 = 255。

所以我们的 ARGB 颜色是 80,00,00,FF。

于 2011-03-29T09:44:34.737 回答
1

选择黑色和白色作为背景颜色是最好的选择,既便于计算,又能保证结果的准确性。大量滥用符号......

  • a(RGB) + (1-a)0xFFFFFF = 0x7F7FFF
  • a(RGB) + (1-a)0x000000 = 0x000080

第一个减去第二个...

  • (1-a)0xFFFFFF = 0x7F7FFF-0x000080 = 0x7F7F7F

所以

  • (1-a) = 0x7F/0xFF
  • a = (0xFF-0x7F)/0xFF = 0x80/0xFF
  • A = 0x80

和 RGB = (a(RGB))/a = 0x000080/a = 0x0000FF

您可以使用其他选择的背景颜色执行非常相似的操作。a 越小,两种背景颜色越接近,您确定 RGBA 值的准确度就越低。考虑 A=0 或两种背景颜色相同的极端情况。

于 2011-03-29T10:27:55.637 回答