Перетворити колір RGBA на RGB


79

Як перетворити кортеж кольорів RGBA, приклад (96, 96, 96, 202), у відповідний кортеж кольорів RGB?

Редагувати:

Я хочу отримати значення RGB, яке найбільше нагадує візуально кортеж RGBA на білому тлі.


3
Чи не просто так (96,96,96)?
Лазар

24
Це залежить від кольору фонового пікселя.
Frank Bollack

5
Ви просто хочете видалити альфа-канал? Або ви хочете отримати RGB результат накладання RGBA на (наприклад, білий фон)?
Ben James

1
Можливо, ви захочете прочитати відому статтю "Складання цифрових зображень" (від Портера та Даффа), щоб отримати докладні відомості про альфа-композицію: keithp.com/~keithp/porterduff
kusma

Відповідь Андраша Золтана та hkurabko також корисні для обчислення опозиції, я маю на увазі, якщо у вас різні кольори, що поєднуються з альфа-кодами, і у вас є оригінальні фони (матові), тоді ви можете обчислити оригінальний колір RGBA, саме це я і шукав while;)
nacho4d

Відповіді:


90

Я підтримав відповідь Йоганнеса, бо він у цьому прав.

* Було висловлено кілька коментарів щодо того, що моя оригінальна відповідь була неправильною. Це спрацювало, якщо значення альфа були інвертовані від нормальних. Однак за визначенням це в більшості випадків не працює. Тому я оновив наведену нижче формулу, щоб вона була правильною для звичайного випадку. Це в кінцевому підсумку дорівнює відповіді @ hkurabko нижче *

Однак більш конкретна відповідь включає значення альфа у фактичний результат кольору на основі непрозорого кольору фону (або „матового“, як це згадується).

Для цього існує алгоритм (із цього посилання на Вікіпедію):

  • Нормалізуйте значення RGBA так, щоб усі вони були від 0 до 1 - просто розділіть кожне значення на 255, щоб зробити це. Ми назвемо результат Source.
  • Нормалізуйте також матовий колір (чорний, білий, що завгодно). Результат ми будемо називати BGColor Приміткою - якщо колір тла також прозорий, то вам доведеться повторити процес для цього (знову ж, вибравши матовий), щоб отримати вихідний RGB для цієї операції.
  • Тепер перетворення визначається як (у повному коді psuedo тут!):

    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, переконайтесь, що ви встановили обмеження на 255, якщо якесь із комбінованих значень перевищує 1,0 (це надмірна експозиція, і з цим працюють більш складні алгоритми які включають обробку цілого зображення тощо).

EDIT: У своєму запитанні ви сказали, що хочете білий фон - у такому випадку просто зафіксуйте BGColor на 255 255 255.


9
У світлі редагування питання це дуже точна та хороша відповідь. Я видалив своє і сподіваюся, що ви роздуєтеся, оскільки ви пояснили справи краще :)
Joey

Я думаю, що ця відповідь передбачає, що кольором тла є rgb, а не rgba.
Лев

Це незвично, якщо врахувати, що RGBA (0,0,0,1) повністю непрозорий чорний. Але за вказаного алгоритму він був би повністю прозорим чорним. Я думаю, що переставлення алгоритму з урахуванням цього зробило б його більш корисним ресурсом та кращою відповіддю на питання.
Bryan Rayner

1
@BryanRayner додав кілька змін до моєї відповіді. Я регулярно набираю голосів за цю відповідь, і цілком можливо, що деякі люди знаходять її, і їм доводиться самостійно інвертувати алгоритм. Було б краще, якби це було повніше. Дякую.
Андраш Золтан,

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

рішення, яке надає Андраш Золтан, слід дещо змінити на:

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)

Ця змінена версія добре працює для мене, тому що в попередній. версія rgba (0,0,0,0) з матовим rgb (ff, ff, ff) буде змінена на rgb (0,0,0).


Я вірю, що ти маєш рацію. Відповідь Вікіпедії та Андраша Золтана дещо інша.
nacho4d

1
Я згоден, використовуйте цю версію, а не @ Andras Zoltan. Для тестового сценарію перетворіть rgba (0,0,0, .7) на фоновий rgb (255,255,255), використовуючи обидві формули; Форума Хкурабка однозначно дає правильну відповідь.
Ryre

4
Andras визначає 0 альфа як непрозорий та 255 як прозорий, тоді як CSS визначає це навпаки. Ця відповідь працює з визначенням CSS альфа-версії.
Кейсі Чу

1
+1 Це працює з найпоширенішим визначенням альфа-версії (0 = прозорий), таким як OpenGL, SDL, графічні редактори.
DLight

+1 - і я оновив свою відповідь, щоб робота з альфою була “правильним шляхом”, як і в цьому. За іронією долі, але я щойно спробував використати для цього моє рішення, я погоджуюсь, що моя оригінальна відповідь, хоча і мала свій власний сенс, насправді не працювала для більшості програм.
Андраш Золтан

8

У моєму випадку я хотів перетворити зображення RGBA в RGB, і наступне працювало так, як очікувалося:

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

5

Це залежить від колірного простору, який ви використовуєте. Якщо RGBA знаходиться в попередньо помноженому колірному просторі і є напівпрозорим, вам потрібно розділити альфа-код, щоб отримати правильний колір RGB. Якщо колір знаходиться у непередмноженому кольоровому просторі, ви можете просто відкинути альфа-канал.


1

Ось зручна функція 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);
}

in sass, ми можемо використовувати:mix($color, white, $alpha*100)
S.Serpooshan

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;
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.