题 将RGBA颜色转换为RGB


如何将RGBA颜色元组(例如96,96,96,202)转换为相应的RGB颜色元组?

编辑:

我想要的是在白色背景上获得与RGBA元组最相似的RGB值。


63
2018-01-12 13:31


起源


那不就是(96,96,96)吗? - Lazarus
这取决于背景像素的颜色。 - Frank Bollack
你只是想删除alpha通道吗?或者你想要RGBA在一个(例如)白色背景上叠加的结果吗? - Ben James
您可能想要阅读着名论文“合成数字图像”(由Porter和Duff撰写),以获取有关alpha合成的完整详细信息: keithp.com/~keithp/porterduff - kusma
Andras Zoltan和hkurabko的答案对于计算对位也很有用,我的意思是如果你有各种alpha混合颜色并且有原始背景(遮罩),那么你可以计算出原来的RGBA颜色,这就是我一直在寻找的颜色而;) - nacho4d


答案:


我赞成约翰内斯的答案,因为他是对的。

*有人评论我的原始答案不正确。如果alpha值与正常值相反,它就有效。但是,根据定义,这在大多数情况下都不起作用。因此,我已将下面的公式更新为正常情况。这最终等于@ hkurabko的答案*

然而,更具体的答案是将alpha值合并到基于不透明背景颜色(或其所指的“遮罩”)的实际颜色结果中。

有一个算法(来自 这个 维基百科链接):

  • 归一化RGBA值,使它们都在0和1之间 - 只需将每个值除以255即可。我们会调用结果 Source
  • 也可以将哑光颜色标准化(黑色,白色等)。我们会调用结果 BGColor  注意  - 如果背景颜色也是透明的,那么您必须首先递归该过程(再次选择遮罩)以获取此操作的源RGB。
  • 现在,转换定义为(在这里完整的伪代码!):

    Source => Target = (BGColor + Source) =
    Target.R = ((1 - Source.A) * BGColor.R) + (Source.A * Source.R)
    Target.G = ((1 - Source.A) * BGColor.G) + (Source.A * Source.G)
    Target.B = ((1 - Source.A) * BGColor.B) + (Source.A * Source.B)
    

获得最终的0-255值 Target 你只需将所有标准化值乘以255,如果任何组合值超过1.0,则确保上限为255(这是过度曝光,有更复杂的算法处理这涉及整个图像处理等) 。

编辑:在你的问题中,你说你想要一个白色背景 - 在这种情况下,只需将BGColor修复为255,255,255。


78
2018-01-12 13:55



根据问题编辑,这是一个非常准确和好的答案。我删除了我的,希望你泡起来,因为你解释了事情的方式更好:) - Joey
谢谢约翰内斯 - 非常善良:) - Andras Zoltan
我认为这个答案假设背景颜色是rgb,而不是rgba。 - Leo
@BryanRayner在我的回答中添加了一些编辑。我经常获得这个答案的投票,有些人可能会发现它,不得不自己反转算法。如果更完整的话会更好。谢谢。 - Andras Zoltan
如果有人仍然感兴趣,这个JSBin允许观察被转换的颜色。它也可以用作javacript函数。我使用BGColor作为白色,因为我只是不理解遮罩概念(对不起!)。链接如下: jsbin.com/qocixeh/edit?html,js,console,output 还有一个要点: gist.github.com/vladimirbrasil/bd139851ff757a1c8cb46fac93e733eb 希望它也有帮助。万分感谢答案! - Vladimir Brasil


嗯......关于

http://en.wikipedia.org/wiki/Alpha_compositing#Alpha_blending

Andras Zoltan提供的解决方案应略微改为:

Source => Target = (BGColor + Source) =
Target.R = ((1 - Source.A) * BGColor.R) + (Source.A * Source.R)
Target.G = ((1 - Source.A) * BGColor.G) + (Source.A * Source.G)
Target.B = ((1 - Source.A) * BGColor.B) + (Source.A * Source.B)

这个改变版本对我来说很好,因为在prev。使用matte rgb(ff,ff,ff)的版本rgba(0,0,0,0)将更改为rgb(0,0,0)。


32
2018-04-15 12:36



我相信你是对的。维基百科和Andras Zoltan的答案有点不同。 - nacho4d
我同意,使用这个版本,而不是@Andras Zoltan的。对于测试场景,使用两个公式在背景rgb(255,255,255)上转换rgba(0,0,0,.7); hkurabko的forumala显然产生了正确的答案。 - Ryre
Andras将0 alpha定义为不透明,将255定义为透明,而CSS则将其定义为相反的方式。这个答案适用于CSS的alpha定义。 - Casey Chu
+1这适用于最常见的alpha(0 =透明)定义,如OpenGL,SDL,图形编辑器。 - DLight
+1 - 我已经更新了我的回答,使用alpha就是'正确的方式',就像这一样。具有讽刺意味的是,刚刚尝试使用我的解决方案来做到这一点,我同意我的原始答案,虽然它有其自身的意义,但并不适用于大多数应用程序。 - Andras Zoltan


这取决于您使用的色彩空间。如果RGBA处于预乘色空间并且是半透明的,则需要将alpha分割以获得正确的RGB颜色。如果颜色位于非预乘颜色空间中,则可以丢弃Alpha通道。


4
2018-01-12 13:39





在我的情况下,我想将RGBA图像转换为RGB,并且以下工作正常:

rgbImage = cv2.cvtColor(npimage, cv2.COLOR_RGBA2RGB)

2
2018-04-17 17:22





这是一个方便的SASS功能,符合Andras和hkurabko的答案。

@function rgba_blend($fore, $back) {
  $ored: ((1 - alpha($fore)) * red($back) ) + (alpha($fore) * red($fore));
  $ogreen: ((1 - alpha($fore)) * green($back) ) + (alpha($fore) * green($fore));
  $oblue: ((1 - alpha($fore)) * blue($back) ) + (alpha($fore) * blue($fore));
  @return rgb($ored, $ogreen, $oblue);
}

用法:

$my_color: rgba(red, 0.5); // build a color with alpha for below

#a_div {
  background-color: rgba_blend($my_color, white);
}

1
2018-02-15 20:36





这是一些java代码(适用于Android API 24):

        //int rgb_background = Color.parseColor("#ffffff"); //white background
        //int rgba_color = Color.parseColor("#8a000000"); //textViewColor 

        int defaultTextViewColor = textView.getTextColors().getDefaultColor();

        int argb = defaultTextViewColor;
        int alpha = 0xFF & (argb >> 24);
        int red = 0xFF & (argb >> 16);
        int green = 0xFF & (argb >> 8);
        int blue = 0xFF & (argb >> 0);
        float alphaFloat = (float)alpha / 255;

        String colorStr = rgbaToRGB(255, 255, 255, red, green, blue, alphaFloat);

功能:

protected String rgbaToRGB(int rgb_background_red, int rgb_background_green, int rgb_background_blue,
                        int rgba_color_red, int rgba_color_green, int rgba_color_blue, float alpha) {

    float red = (1 - alpha) * rgb_background_red + alpha * rgba_color_red;
    float green = (1 - alpha) * rgb_background_green + alpha * rgba_color_green;
    float blue = (1 - alpha) * rgb_background_blue + alpha * rgba_color_blue;

    String redStr = Integer.toHexString((int) red);
    String greenStr = Integer.toHexString((int) green);
    String blueStr = Integer.toHexString((int) blue);

    String colorHex = "#" + redStr + greenStr + blueStr;

    //return Color.parseColor(colorHex);
    return colorHex;
}

0
2018-04-06 22:15