web-dev-qa-db-ja.com

RGBAカラーをRGBに変換

RGBAカラータプルの例(96、96、96、202)を対応するRGBカラータプルに変換する方法は?

編集:

私が欲しいのは、RGBAタプルに最も近いRGB値を白い背景で視覚的に取得することです。

72
jack

ヨハネスがそのことについて正しいので、私はヨハネスの答えを支持しました。

*私の元の答えが正しくないというコメントがいくつか寄せられました。アルファ値が通常と逆の場合に機能しました。ただし、定義上、これはほとんどの場合機能しません。そのため、通常の場合に合わせて以下の式を更新しました。これは、以下の@hkurabkoの回答と等しくなります*

ただし、より具体的な答えは、不透明な背景色(または「マット」と呼ばれる)に基づいて、実際の色結果にアルファ値を組み込みます。

これにはアルゴリズムがあります( this wikipediaリンクから):

  • RGBA値を正規化して、すべて0〜1になるようにします。これを行うには、各値を255で除算します。結果をSourceと呼びます。
  • マット色(黒、白など)も正規化します。結果をBGColorNoteと呼びます-背景色も透明な場合は、プロセスを再帰する必要がありますこの操作のソース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)
    

Targetの最終的な0〜255の値を取得するには、すべての正規化された値を255で乗算します。結合された値のいずれかが1.0を超える場合、255これを処理するより複雑なアルゴリズムで、画像全体の処理などが含まれます)。

編集:あなたの質問で、あなたは白い背景が欲しいと言いました-その場合、BGColorを255,255,255に修正してください。

86
Andras Zoltan

hm ...に関して

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)

この変更されたバージョンは、私にとってはうまく機能します。 Matte rgb(ff、ff、ff)を含むバージョンrgba(0,0,0,0)は、rgb(0,0,0)に変更されます。

37
hkurabko

これは、使用する色空間によって異なります。 RGBAがあらかじめ乗算された色空間にあり、半透明である場合、正しいRGB色を得るためにアルファを分割する必要があります。色が事前乗算されていない色空間にある場合は、アルファチャネルを破棄できます。

4
kusma

私の場合、RGBAイメージをRGBに変換したかったのですが、以下は期待どおりに機能しました。

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

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;
}
1
live-love

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);
}
1
Rohanthewiz