Вы можете конвертировать ваши изображения Pillow в NumPy массивы и использовать векторизованные операции для ускорения вашей обработки.
Имея img1.png
(полностью непрозрачные случайные пиксели)
и img2.png
(полностью прозрачные фоновые пиксели, полностью непрозрачные красные пиксели)
один можно использовать этот подход для достижения описанного поведения:
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
):
Если у вас "гладкая" прозрачность, т.е. ваш альфа-канал имеет значения из всего диапазона [0 ... 255]
, мы могли бы изменить код. Имея такой img2_smooth.png
, который будет измененным кодом:
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
:
Надеюсь, это поможет!
----------------------------------------
System information
----------------------------------------
Platform: Windows-10-10.0.16299-SP0
Python: 3.8.1
NumPy: 1.18.1
Pillow: 7.0.0
----------------------------------------