如何从两个 RGB 值中找到一种颜色的 RGBA 值?

发布于 2024-10-27 05:59:59 字数 292 浏览 7 评论 0原文

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

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

或者这甚至可能吗???

I have a hunch this has been done before but I am a total layman at this and don't know how to begin to ask the right question. So I will describe what I am trying to do...

I have an unknown ARGB color. I only know its absolute RGB value as displayed over two known opaque background colors, for example black 0x000000 and white 0xFFFFFF. So, to continue the example, if I know that the ARGB color is RGB 0x000080 equivalent when displayed over 0x000000 and I know that the same ARGB color is RGB 0x7F7FFF equivalent when displayed over 0xFFFFFF, is there a way to compute what the original ARGB color is?

Or is this even possible???

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

就像说晚安 2024-11-03 05:59:59

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

实际上,您应该计算对所有三个 {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。

So, you know that putting (a,r,g,b) over (r1,g1,b1) gives you (R1,G1,B1) and that putting it over (r2,g2,b2) gives you (R2,G2,B2). In other words -- incidentally I'm going to work here in units where a ranges from 0 to 1 -- you know (1-a)r1+ar=R1, (1-a)r2+ar=R2, etc. Take those two and subtract: you get (1-a)(r1-r2)=R1-R2 and hence a=1-(R1-R2)/(r1-r2). Once you know a, you can work everything else out.

You should actually compute the values of a you get from doing that calculation on all three of {R,G,B} and average them or something, to reduce the effects of roundoff error. In fact I'd recommend that you take a = 1 - [(R1-R2)sign(r1-r2) + (G1-G2)sign(g1-g2) + (B1-B2)sign(b1-b2)] / (|r1-r2|+|g1-g2|+|b1-b2), which amounts to weighting the more reliable colours more highly.

Now you have, e.g., r = (R1-(1-a)r1)/a = (R2-(1-a)r2)/a. These two would be equal if you had infinite-precision values for a,r,g,b, but of course in practice they may differ slightly. Average them: r = [(R1+R2)-(1-a)(r1+r2)]/2a.

If your value of a happens to be very small then you'll get only rather unreliable information about r,g,b. (In the limit where a=0 you'll get no information at all, and there's obviously nothing you can do about that.) It's possible that you may get numbers outside the range 0..255, in which case I don't think you can do better than just clipping.

Here's how it works out for your particular example. (r1,g1,b1)=(0,0,0); (r2,g2,b2)=(255,255,255); (R1,G1,B1)=(0,0,128); (R2,G2,B2)=(127,127,255). So a = 1 - [127+127+127]/[255+255+255] = 128/255, which happens to be one of the 256 actually-possible values of a. (If it weren't, we should probably round it at this stage.)

Now r = (127-255*127/255)*255/256 = 0; likewise g = 0; and b = (383-255*127/255)*255/256 = 255.

So our ARGB colour was 80,00,00,FF.

慈悲佛祖 2024-11-03 05:59:59

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

  • 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 或两个背景颜色相同的极端情况。

Choosing black and white as the background colors is the best choice, both for ease of calculation and accuracy of result. With lots of abuse of notation....

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

Subtracting the second from the first...

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

So

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

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

You can do something very similar with other choices of background color. The smaller a is and the closer the two background colors are the less accurately you will be able to determine the RGBA value. Consider the extreme cases where A=0 or where the two background colors are the same.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文