将RGBA颜色转换为RGB


79

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

编辑:

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


3
难道不是(96,96,96)吗?
拉撒路

24
这取决于背景像素的颜色。
Frank Bollack 2010年

5
您是否只想删除Alpha通道?还是您想要将RGBA叠加在(例如)白色背景上的RGB结果?
本·詹姆斯

1
您可能需要阅读著名的论文“合成数字图像”(由Porter和Duff撰写
kusma 2010年

Andras Zoltan和hkurabko的答案对于计算对立面也很有用,我的意思是,如果您具有各种alpha混合颜色并具有其原始背景(无光泽),那么您可以计算出我一直在寻找的RGBA原始颜色。 while;)
nacho4d 2010年

Answers:


90

我赞成约翰尼斯的回答,因为他对此是正确的。

*有人提出我的原始答案不正确的评论。如果alpha值与正常值相反,则可以正常工作。但是,根据定义,这在大多数情况下不起作用。因此,我更新了以下公式以适合正常情况。最终等于@hkurabko在下面的回答*

但是,一个更具体的答案是将alpha值基于不透明的背景色(或称为“遮罩”)合并到实际的颜色结果中。

为此有一个算法(来自Wikipedia链接):

  • 标准化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。


9
根据问题编辑,这是一个非常准确且很好的答案。我删除了我的邮件,并希望您能如愿以偿,因为您对问题的解释更好:)
Joey 2010年

我认为此答案假设背景色是rgb,而不是rgba。
2014年

考虑到RGBA(0,0,0,1)是完全不透明的黑色,这是不寻常的。但是使用给定的算法,它将是完全透明的黑色。我认为重新排列算法以反映这一点将使其成为更有用的资源并更好地回答问题。
Bryan Rayner 2014年

1
@BryanRayner已对我的答案进行了一些编辑。我经常为此答案投票,有可能有人发现了它,不得不自己反转算法。如果它更完整会更好。谢谢。
Andras Zoltan 2014年

2
如果仍然有人感兴趣,则可以使用此JSBin观看正在变换的颜色。它也可以用作javacript函数。我将BGColor用作白色,因为我只是不了解遮罩的概念(对不起!)。链接如下:jsbin.com/qocixeh/edit?html , js , console , output以及要点:gist.github.com/vladimirbrasil/bd139851ff757a1c8cb46fac93e733eb希望它也能有所帮助。非常感谢您的回答!
弗拉基米尔·巴西

40

嗯...关于

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)

这个变化的版本对我来说很好用,因为在上一版中。带有哑光rgb(ff,ff,ff)的版本rgba(0,0,0,0)将更改为rgb(0,0,0)。


我相信你是对的。维基百科和Andras Zoltan的答案有些不同。
nacho4d

1
我同意,使用此版本,而不是@Andras Zoltan的版本。对于测试方案,使用两个公式在背景rgb(255,255,255)上转换rgba(0,0,0,.7);hkurabko的forumala显然会给出正确的答案。
瑞尔(Ryre)2011年

4
Andras将0 alpha定义为不透明,将255定义为透明,而CSS将其定义为相反。此答案与CSS的alpha定义一起使用。
Casey Chu

1
+1这适用于最常见的alpha定义(0 =透明),例如OpenGL,SDL,图形编辑器。
DLight

+1-我也更新了我的答案,使其也可以按照“正确的方向”使用alpha。具有讽刺意味的是,我刚刚尝试使用我的解决方案来完成此任务,但我同意我的原始答案尽管具有其自身的意义,但实际上不适用于大多数应用程序。
安德拉斯·佐尔坦

7

就我而言,我想将RGBA图像转换为RGB,并且以下功能按预期工作:

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

5

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


1

根据Andras和hkurabko的回答,这是一个便捷的SASS功能。

@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);
}

mix($color, white, $alpha*100)
无礼的情况下

1

这是一些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;
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.