Изменение оттенка цвета rgba - программирование

Изменение оттенка цвета rgba

Я рисую кучу данных в лог-шкале в виде графика разброса в matplotlib (на всякий случай, когда среда имеет значение) с использованием цветов RGBA. То, что я хотел бы сделать, - это как только я построил все, я хочу выделить отдельные точки разброса и изменить их оттенок на оттенок некоторого RGB-цвета, но сохраняя старую альфа-значение. То, как я сейчас это делаю, это:

oldHSV = rgb_to_hsv(oldRGBA[:3])
newHSV = rgb_to_hsv(newRGB)
oldHSV[0] = newHSV[0]
newRGBA = hsv_to_rgb(oldHSV).tolist() + [oldRGBA[3]]

то есть. Я беру RGB часть старого значения RGBA, превращаю его в HSV, делаю то же самое для нового намеченного цвета RGB, затем заменяем оттенок, возвращаем его обратно в RGB и добавляем к старому альфа-значению.

Поскольку я делаю это тысячи раз, это может занять значительно больше времени, чем я хотел бы провести здесь. Одно из возможных исправлений заключалось бы в том, чтобы вникать в преобразование между RGB и HSV и выяснить, как это сделать за один раз, но я надеялся, что люди, которые знают, как обращаться с цветом (я действительно этого не делаю), выяснили простые и эффективные способы сделать это.

Как мне изменить оттенок заданного цвета RGBA A на определенный RGB-цвет B при сохранении альфа-значения A? Может ли использование другой цветовой модели (например, HSL) упростить задачу, и если да, то это поможет?

4b9b3361

Ответ 1

Вот решение, чтобы выполнить все замены за один раз:

import matplotlib.colors as clr
import matplotlib.pyplot as plt
import numpy as np


N = 100000
x = 1.2 + 800.0 * np.random.rand(N)
y = 1.2 + 800.0 * np.random.rand(N)
# Generate random colors of the form (r, g, b, a) where r = 0.0
colors = np.random.rand(4 * N).reshape((N, 4))
colors[:, 0] = 0.0
area = np.pi * (5 * np.random.rand(N))**2

fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
pcol = ax.scatter(x, y, s=area, c=colors)
ax.set_xscale('log')
ax.set_yscale('log')

# Save initial figure
plt.savefig("hue.jpg")

oldRGBA = pcol.get_facecolors().reshape((N, 1, 4))
oldRGB = oldRGBA[:, :, :3]
newRGB = oldRGB
newRGB[:, :, 0] = 1.0 # Set red component to 1.0
oldHSV = clr.rgb_to_hsv(oldRGB)
newHSV = clr.rgb_to_hsv(newRGB)
oldHSV[:, :, 0] = newHSV[:, :, 0]
newRGBA = np.copy(oldRGBA)
newRGBA[:, :, :3] = clr.rgb_to_hsv(oldHSV)
pcol.set_facecolors(newRGBA[:, 0, :])

# Save modified figure
plt.savefig("hue_bis.jpg")

plt.close()

Как вы можете видеть, этот код пытается построить 100000 точек, и на самом деле это удалось сделать за 2 секунды. Вот цифры:

hue.jpg

и:

hue_bis.jpg

Что касается двух последних вопросов:

Как изменить оттенок заданного RGBA-цвета A на тот, который соответствует RGB-цвету B, сохраняя альфа-значение A?

и:

Использование другой цветовой модели (например, HSL) упростит задачу, и если это так, что поможет

Я думаю, что ваш подход к такой модификации заметен, это позволяет избежать расчетов вручную (см. HSL и HSV). Использование другой цветовой модели возможно, и HSL и HSV позволяют изменять оттенок, не влияя на другие параметры, но это только другой способ сделать это, а не лучший.

Надеюсь, это поможет.

Ответ 2

Должно быть возможно извлечь альфа из oldRGBA и непосредственно применить ее к newRGB:

newRGBA = colors.to_rgba(newRGB, alpha=oldRGBA[3])

Примечание. Я никогда не использовал matplotlib, я предполагаю, что альфа-компонент является 4-м элементом цвета