Рейтинг@Mail.ru

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).

прикладное, Программирование , ,

Пожалуйста, оцените полезность и качество данной статьи. Одна звезда - плохо, 5 - хорошо.
1 звезда2 звезды3 звезды4 звезды5 звёзд (4 голосов, средний: 4,25 из 5)
Loading ... Loading ...

  1. sansentrailless
    17 Ноябрь 2010 в 16:25 | #1

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

  2. 26 Ноябрь 2010 в 12:56 | #2

    И Вам спасибо за замечание, сейчас поправим. :)

  1. Пока что нет уведомлений.
*