Уверенный, что это выполнимо.
Предположим, что вы начинаете с изображения без прозрачности (потому что в противном случае ваш вопрос неоднозначен).
Шаг 1: Добавить альфа-плоскость. Это всего лишь putalpha
, если вы не имеете дело с непланарным изображением, и в этом случае вам нужно сначала преобразовать его в RGB или L.
Шаг 2: Перебрать пиксели, которые вы хотите изменить, используя массив пикселей, возвращенное load
(или getpixel
и setpixel
, если вам приходится иметь дело с древними версиями PIL).
Шаг 3: Нет шага 3. Если вы не посчитаете сохранение изображения. В этом случае, OK, шаг 3 сохраняет изображение.
from PIL import Image
im = Image.open('bird.jpg')
im.putalpha(255)
width, height = im.size
pixels = im.load()
for y in range(int(height*.55), int(height*.75)):
alpha = 255-int((y - height*.55)/height/.20 * 255)
for x in range(width):
pixels[x, y] = pixels[x, y][:3] + (alpha,)
for y in range(y, height):
for x in range(width):
pixels[x, y] = pixels[x, y][:3] + (0,)
im.save('birdfade.png')
Здесь альфа падает линейно от 255 до 0; вы хотите, чтобы он упал по другой кривой, или вы используете RGB16 вместо RGB8, или используете L вместо RGB, вы должны выяснить, как его изменить.
Если вы хотите сделать это быстрее, вы можете использовать NumPy вместо цикла Python для шага 2. Или вы можете обратить шаги 1 и 2-построить альфа-плоскость заранее, и применять все сразу передавая его putalpha
вместо 255
. Или ... Поскольку это заняло полсекунды на самом большом изображении, с которым я лежал, я не слишком беспокоюсь о производительности, если вам не нужно сделать миллион из них, и вам нужна более быстрая версия.
К сожалению, выиграл» я смогу применить ваш ответ на практике в течение нескольких часов, но выглядит хорошо. Я скоро уточню. Кроме того, я забыл упомянуть о том, что изображения (там будет немало, так что эффективность будет приятной) - все jpeg, но jpeg не поддерживает прозрачность, поэтому его нужно сохранить как png, правильно? – RTF
@RTF: Правильно, вам нужно будет сохранить PNG (или что-то еще, что поддерживает прозрачность). Между тем, сколько «довольно много»? И насколько велики файлы? Проводить дополнительное часовое кодирование и отлаживать что-то более сложное, чтобы сэкономить 10 секунд времени выполнения, не стоит; если это сэкономит вам дополнительные 3 часа работы каждый месяц в течение следующих 3 лет, это совсем другая история ... – abarnert
Может быть несколько сотен изображений, вытащенных из веб-службы по одному, около 400 тыс. 500 тыс. каждый (итоговые png будут быть ~ 1.75mb, намного больше, чем хотелось бы, но у меня нет выбора, если я хочу прозрачность).Как это бывает, каждый запрос изображения требует не менее 1 секунды между запросами, чтобы предотвратить дросселирование, и сейчас я сплю для большей части этого. Поэтому я возьму это, а не возьму другую библиотеку (numpy). – RTF