Вот попытка использовать PIL
вместо numpy
. Это должно быть легко конвертировать. Без копии Photoshop для сравнения я не могу гарантировать, что она точно соответствует выходным данным, но она дает точные значения для примера, показанного в вашей ссылке. Значения r_w, y_w, g_w, c_w, b_w, m_w
- это веса, применяемые к каждому цвету, с 1,0, равным 100% в соответствующем слайдере Photoshop. Естественно, они также могут быть отрицательными.
from PIL import Image
im = Image.open(r'c:\temp\temp.png')
def ps_black_and_white(im, weights):
r_w, y_w, g_w, c_w, b_w, m_w = [w/100 for w in weights]
im = im.convert('RGB')
pix = im.load()
for y in range(im.size[1]):
for x in range(im.size[0]):
r, g, b = pix[x, y]
gray = min([r, g, b])
r -= gray
g -= gray
b -= gray
if r == 0:
cyan = min(g, b)
g -= cyan
b -= cyan
gray += cyan * c_w + g * g_w + b * b_w
elif g == 0:
magenta = min(r, b)
r -= magenta
b -= magenta
gray += magenta * m_w + r * r_w + b * b_w
else:
yellow = min(r, g)
r -= yellow
g -= yellow
gray += yellow * y_w + r * r_w + g * g_w
gray = max(0, min(255, int(round(gray))))
pix[x, y] = (gray, gray, gray)
return im
Используя это предоставленное тестовое изображение, вот несколько примеров результатов.
ps_black_and_white(im, [-17, 300, -100, 300, -200, 300])
ps_black_and_white(im, [40, 60, 40, 60, 20, 80])
ps_black_and_white(im, [106, 65, 17, 17, 104, 19])