Добавление изображений с помощью python и imagemagick

Большинство людей рекомендуют «палочку», когда дело доходит до imagemagick для python, но как я могу добавлять изображения, используя ее в python? Я хочу добавить ярлыки в нижнюю часть изображений, используя imagemagick в python: http://www.imagemagick.org/Usage/annotating/, но wand API кажется очень простым и не имеет большого количества команд imgemagick, включая метки и добавление.

Есть ли другой способ использовать imagemagick в python? мои изображения имеют тип png и представляют собой потоки BytesIO внутри кода Python, а не файлы, поэтому я не могу передать их в imagemagick с помощью командной строки и не могу сохранить их в каком-либо временном файле.


person r3zaxd1    schedule 27.03.2018    source источник
comment
См. текст рисования палочкой на docs.wand-py.org. /ru/0.4.4/guide/draw.html#texts   -  person fmw42    schedule 27.03.2018
comment
@ fmw42 Да, я видел это, но я ищу добавление метки, такой как ссылка, которую я отправил, иначе это было бы намного медленнее, если я хочу создать пустое изображение, скопируйте мое изображение поверх него, создайте меньший для внизу и напишите на нем текст и скопируйте вниз.   -  person r3zaxd1    schedule 27.03.2018
comment
Я не знаю Wand, но из того, что я вижу, вы должны иметь возможность рисовать текст (или другие примитивы) непосредственно на изображении, используя метод with Image, указав изображение, на котором вы хотите рисовать.   -  person fmw42    schedule 27.03.2018


Ответы (2)


Я не совсем уверен, о чем вы просите, но я предполагаю, что вы хотите написать метку «под» изображением. Вот пример с библиотекой wand.

from wand.image import Image
from wand.compat import nested
from wand.color import Color
from wand.font import Font

with nested(Image(filename='logo:'),
            Image(filename='null:')) as (source, text):
    text.font = Font('Impact', 64)
    text.read(filename='label:Hello world!')
    largest_width = max(source.width, text.width)
    offset = (largest_width - min(source.width, text.width)) / 2
    with Image(width=largest_width,
               height=source.height + text.height,
               background=Color('WHITE')) as dst:
        dst.composite(source, 0, 0)
        dst.composite(text, int(offset), source.height)
        dst.save(filename="output.png")

Привет, мир

Обзор

with nested(Image(filename='logo:'),
            Image(filename='null:')) as (source, text):

Создайте два изображения. Вы будете нести ответственность за замену logo: изображения вашим буфером ByteIO. Изображение null: является заполнителем для размещения экземпляра жезла.

    text.font = Font('Impact', 64)
    text.read(filename='label:Hello world!')

Это определяет шрифт и текст для рисования. Протокол label: можно заменить на caption: для дополнительного поведения.

    with Image(width=largest_width,
               height=source.height + text.height,
               background=Color('WHITE')) as dst:

Создайте третье «пустое» изображение, достаточно большое, чтобы включить оба изображения.

        dst.composite(source, 0, 0)
        dst.composite(text, int(offset), source.height)

Скопируйте данные изображения из source и text в новое изображение.

person emcconville    schedule 27.03.2018
comment
@emcconville. Спасибо за добавление правильного кода. Я думал, что это возможно с помощью Wand, но я не пользователь Wand. - person fmw42; 28.03.2018
comment
спасибо за ваш код, он очень близок к тому, что мне нужно, и я изменил его в соответствии со своими потребностями (BytesIO), и этот пример точно показывает, почему я настаивал на использовании палочки, я использовал этот код и код из решения Mick_, чтобы добавить тот же текст к тому же picture, wand (imagemagick) сделал это за 140 мс, а PIL - около 900 мс. - person r3zaxd1; 28.03.2018

Imagemagick великолепен, но у него крутая кривая обучения. Вам необходимо установить сторонний ImageMagick (должен быть 32 или 64 бит в зависимости от вашей версии Python). Одна только установка - это боль, учитывая, что вам нужно добавить ее в путь, а исполняемый файл необходим для запуска вашего скрипта.

Подумайте о чем-то более портативном и компактном, например, о Pillow, в котором есть ряд функций для достижения вашей цели.

pip install pillow

В подушке вы можете читать изображения из BytesIO. А также рисовать или печатать на них. Доступно несколько вариантов.

from PIL import Image, ImageDraw
import io


# Reading bytes from file but you can skip that and simply open your bytes like below.

with open('picture.jpg', 'rb') as f:
    im = Image.open(io.BytesIO(f.read()))
    draw = ImageDraw.Draw(im)
    draw.text((10,10), "Hello World", fill=(255))
    im.show() # do whatever you like with the image

Проверьте документы для получения дополнительных примеров. https://pillow.readthedocs.io/en/latest/

person Mick_    schedule 27.03.2018