Как установить прозрачное изображение для непрозрачной части из другого изображения? - PullRequest
0 голосов
/ 16 февраля 2020

У меня есть два изображения: img1 и img2, а img2 прозрачно, за исключением одной части изображения.

Используя Подушку, как обрезать непрозрачную часть img2 с img1? В результате я хотел бы получить img1 с прозрачной частью, где img2 непрозрачный.

img1 и img2 имеют одинаковый размер.

1 Ответ

2 голосов
/ 17 февраля 2020

Вы можете конвертировать ваши изображения Pillow в NumPy массивы и использовать векторизованные операции для ускорения вашей обработки.

Имея img1.png (полностью непрозрачные случайные пиксели)

img1

и img2.png (полностью прозрачные фоновые пиксели, полностью непрозрачные красные пиксели)

img

один можно использовать этот подход для достижения описанного поведения:

import numpy as np
from PIL import Image

# Open images via Pillow
img1 = Image.open('img1.png')
img2 = Image.open('img2.png')

# Convert images to NumPy arrays
img1_np = np.array(img1)
img2_np = np.array(img2)

# Get (only full) opaque pixels in img2 as mask
mask = img2_np[:, :, 3] == 255

# Make pixels in img1 within mask transparent
img1_np[mask, 3] = 0

# Convert image back to Pillow
img1 = Image.fromarray(img1_np)

# Save image
img1.save('img1_mod.png')

Модифицированный img1_mod.png будет выглядеть следующим образом (полностью непрозрачные случайные пиксели фона, прозрачные пиксели там, где красный квадрат в img2.png):

img1_mod

Если у вас "гладкая" прозрачность, т.е. ваш альфа-канал имеет значения из всего диапазона [0 ... 255], мы могли бы изменить код. Имея такой img2_smooth.png

img2_smooth

, который будет измененным кодом:

import numpy as np
from PIL import Image

# Open images via Pillow
img1 = Image.open('img1.png')
img2 = Image.open('img2_smooth.png')

# Convert images to NumPy arrays
img1_np = np.array(img1)
img2_np = np.array(img2)

# Get (also partially) opaque pixels in img2 as mask         # <--
mask = img2_np[:, :, 3] > 0                                  # <--

# Make pixels in img1 within mask (partially) transparent    # <--
img1_np[mask, 3] = 255 - img2_np[mask, 3]                    # <--

# Convert image back to Pillow
img1 = Image.fromarray(img1_np)

# Save image
img1.save('img1_smooth_mod.png')

И это будет новым вывод img1_smooth_mod.png:

img2_smooth_mod

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

----------------------------------------
System information
----------------------------------------
Platform:    Windows-10-10.0.16299-SP0
Python:      3.8.1
NumPy:       1.18.1
Pillow:      7.0.0
----------------------------------------
...