Залейте изображение цветом, но сохраняйте альфа (наложение цвета в PIL) - PullRequest
2 голосов
/ 18 мая 2019

По сути, я пытаюсь сделать функцию, которая будет принимать заданное изображение и цвет. для каждого пикселя изображения он сохранит исходное значение альфа, но изменит цвет на заданный.

например, если функция получает изображение стрелки ниже и красный цвет,

Original image - all colors

Будет выведено следующее изображение:

Result image - red

В Photoshop и других графических редакторах этот эффект называется «наложением цвета». Есть ли быстрый и простой способ достижения того же результата в PIL? Заранее спасибо! (;

Ответы [ 3 ]

3 голосов
/ 18 мая 2019

Один из способов сделать это - создать сплошное красное изображение того же размера, что и оригинал, а затем скопировать в него альфа-канал из исходного изображения:

from PIL import Image

# Open original image and extract the alpha channel
im = Image.open('arrow.png')
alpha = im.getchannel('A')

# Create red image the same size and copy alpha channel across
red = Image.new('RGBA', im.size, color='red')
red.putalpha(alpha) 

enter image description here


Вот второй метод с использованием Numpy:

from PIL import Image
import numpy as np

# Open image
im = Image.open('arrow.png')

# Make into Numpy array
n = np.array(im) 

# Set first three channels to red
n[...,0:3]=[255,0,0] 

# Convert back to PIL Image and save
Image.fromarray(n).save('result.png')

Третий способ - скомпоновать с красной копией аналогичного размера и использовать оригинальную альфа-маску:

from PIL import Image

# Open image
im = Image.open('arrow.png')                                                                                                       

# Make solid red image same size
red = Image.new('RGBA', im.size, color='red')                                                                                      

# Composite the two together, honouring the original mask
im = Image.composite(red,im,im)  

Ключевые слова : Изображение, обработка изображений, Python, Pillow, PIL, Numpy, извлечение альфа, альфа-канал, прозрачность, замена прозрачности, прозрачность копирования, копирование альфа, трансплантация альфа, трансплантация прозрачности.

1 голос
/ 18 мая 2019

Давайте рассмотрим следующее изображение - http://www.libpng.org/pub/png/img_png/globe-scene-fish-bowl-pngcrush.png

image = cv2.imread("/home/thalish/bleed_test/globe-scene-fish-bowl-pngcrush.png",cv2.IMREAD_UNCHANGED)

image[:,:,0],image[:,:,1],image[:,:,2] = (255,0,0) #to replace all pixels with Red but keep alpha channel unchanged

Final Image

0 голосов
/ 18 мая 2019

Попробуйте:

from PIL import Image

# Takes the input image
img = Image.open(r"Arrow.png")

# Getting the dimensions of the image
x, y = img.size

# Obtaining values of Red, Green, Blue for each opaque pixel
red = int(input("Enter the red value you want in each pixel = "))
green = int(input("Enter the green value you want in each pixel = "))
blue = int(input("Enter the blue value you want in each pixel = "))

i = j = 0

# This loop makes sure that alpha only has two discrete values (0 , 255)
# This is to ensure that constant color is obtained, at pixels where transparence may not be 255
# (prevents color escapes at pixels where total transparency is not achieved)
while i < x:
    while j < y:
        r, g, b, a = img.getpixel((i,j))
        if a > 200 and a < 256:
            a = 255
        else:
            a = 0
        img.putpixel((i,j),(r,g,b,a))
        j += 1
    j = 0
    i += 1

i = j = 0

# Two nested loops
# Outer one goes through rows of image
# Inner one (nested one) goes through columns of image
while i < x:
    while j < y:

        # This condition checks, if the value of alpha for that individual pixel is 255 (~opaque), 
        # if true then change its RGB values to user defined values
        if img.getpixel((i,j))[-1] == 255:
            img.putpixel((i,j), (red, green, blue, 255))
        j += 1
    j = 0
    i += 1

img.save("Arrow.png")

ВХОД: -

Enter the red value you want in each pixel = 0
Enter the green value you want in each pixel = 0
Enter the blue value you want in each pixel = 255

ВЫВОД: -

ОБЪЯСНЕНИЕ ДЛЯ ПЕРВОГО ПЕТЛЯ: -

Если первый цикл не выровняется, значения alpha определяются пороговым значением, то в выходном изображении возникает много ошибок. то есть значения пикселей около края объекта имеют тенденцию иметь alpha значения пикселей немного меньше, чем 255 (общая непрозрачность), чтобы включить плавное сглаживание . Если эти пиксели отбрасываются, выходное изображение может выглядеть примерно так: -

Notice the unwanted color's in the edge of the arrow

PS: - Несмотря на то, что OpenCV был бы предпочтительным выбором для большинства аналитиков / экспертов по изображениям, я бы определенно посоветовал вам придерживаться PIL / Pillow в начале, так как это позволяет вам понять основы визуализации в действительно дружественной форме. Нет никаких сомнений в том, что OpenCV намного превосходит PIL практически во всех аспектах, но, тем не менее, если вы изучите PIL в начале, переход от PIL к OpenCV будет гораздо проще выполнить позже.

...