Python: Масштабирование и наложение водяных знаков на изображение.
В данной статье будут рассмотрены некоторые возможности PIL (Python Imaging Library), а именно — использование библиотеки для создания превьюшек и наложения одного изображения на другое. Всё это делается достаточно тривиально, если знать как, ну а те, кто не знает, могут читать дальше ;-).
Начнём с функции масштабирования.
import Image
def create_thumbnails(img, size):
thumbnails = []
for s in size:
if img.size[0] == img.size[1]:
thumbnails.append(img.resize((s, s), Image.ANTIALIAS))
elif img.size[0] > img.size[1]:
ratio = float(img.size[0]) / s
thumbnails.append(img.resize((s, int(img.size[1]/ratio)), Image.ANTIALIAS))
else:
ratio = float(img.size[1]) / s
thumbnails.append(img.resize((int(img.size[0]/ratio), s), Image.ANTIALIAS))
return thumbnails
if __name__ == "__main__":
img = Image.open("1.jpg")
thumbs = create_thumbnails(img, (1000, ))
thumbs.extend(create_thumbnails(img, (500, 250, 100)))
c = 0
for t in thumbs:
t.save("%dt.jpg" % c)
c += 1
UPD: Как оказалось, код выше — велосипед :). Всё делается проще. Вместо вычисления соотношений пишем просто img.thumbnail((100, 100), Image.ANTIALIAS), остально за Вас всё сделает питон… Эхх, никакой свободы мысли ;).
Функция Image.open(), как Вы догадались, открывает изображение для дальнейших манипуляций с ним. Наша функция принимает полученный в результате открытия объект и список размеров (поэтому, если мы передаём один размер, то надо указать в параметрах, например, (100, ), а не просто (100)), по которым потом и будем масштабировать. Масштабирование происходит по большей стороне с сохранением пропорций. Возваращает функция так же список полученных превьюшек.
img.resize() — вторым параметром указывается метод преобразования, с Image.ANTIALIAS получается наиболее лучший вариант, так же можно указать Image.NEAREST, Image.BILINEAR, Image.BICUBIC вместо ANTIALIAS, первым — список из ширины и высоты нового изображения.
Теперь перейдём к водяным знакам. Для начала создадим какой-нибудь рисунок или надпись с прозрачным фоном и сохраним в формате png — это и будет наш водяной знак. Можно накладывать его разным способами, мы реализуем клонирование с заданным интервалом. Итак, вот как это примерно будет выглядеть:
import Image, ImageEnhance
def add_watermark(image, watermark, opacity=1, wm_interval=0):
assert opacity >= 0 and opacity <= 1
if opacity < 1:
if watermark.mode != 'RGBA':
self.watermark = watermark.convert('RGBA')
else:
watermark = watermark.copy()
alpha = watermark.split()[3]
alpha = ImageEnhance.Brightness(alpha).enhance(opacity)
watermark.putalpha(alpha)
layer = Image.new('RGBA', image.size, (0,0,0,0))
for y in range(0, image.size[1], watermark.size[1]+wm_interval):
for x in range(0, image.size[0], watermark.size[0]+wm_interval):
layer.paste(watermark, (x, y))
return Image.composite(layer, image, layer)
if __name__ == "__main__":
img = Image.open("1.jpg")
wm = Image.open("wm.png")
add_watermark(img, wm, 0.5, 50).save("wm_1.jpg")
В этой функции мы уменьшаем прозрачность, если она задана меньше 1, затем создаём новую картинку layer размером с исходное изображение и добавляем на неё водяные знаки с заданным интервалом, наконец возвращаем изображение, полученное из исходной картинки и нашей новой - layer.
Ссылки к статье:
http://code.activestate.com/recipes/362879/ - Watermark with PIL.
- Resize an image (Python).


(4 голосов, средний: 4,25 из 5)
Спасибо за пост. Два дня бился с наложением прозрачного png на картинку.
ЗЫ. У вас в коде » заменились на ‘<’ и ‘>’
В строках:
assert opacity >= 0 and opacity <= 1
if opacity < 1:
И Вам спасибо за замечание, сейчас поправим. :)