Могу ли я получить доступ к API ImageMagick с помощью Python?

#python #imagemagick #image-manipulation #ctypes

#python #imagemagick #обработка изображений #ctypes

Вопрос:

Мне нужно использовать ImageMagick, поскольку в PIL нет доступных функций изображения, которые я ищу. Тем не менее, я хочу использовать Python.

Привязки python (PythonMagick) не обновлялись с 2009 года. Единственное, что я смог найти, это os.system вызовы для использования интерфейса командной строки, но это кажется неуклюжим.

Есть ли какой-либо способ получить доступ к API напрямую, используя ctypes какие-либо преобразования и? В качестве последнего средства есть ли какая-либо другая библиотека, в которой есть множество инструментов для редактирования изображений, таких как ImageMagick, которые я просмотрел?

Ответ №1:

Я бы рекомендовал использовать Wand (пояснения приведены ниже).

Я искал правильную привязку к библиотеке ImageMagick, которая бы:

  • ошибка в работе / без проблем
  • регулярно поддерживается и обновляется
  • разрешить хороший объективный Python

Но на самом деле python API (привязка) имеет слишком много разных (в основном снятых с производства) версий. После прочтения хорошего исторического обзора Бенджамина Швейцера все стало ясно:

  • GraphicsMagick
  • PythonMagick — первая реализация
  • PythonMagickWand / Ахим Домма — первая палочка — реализация CDLL
  • PythonMagickWand / Ян Стивенс
  • MagickFoo — включен в python-magickwand
  • Wand / Hong Minhee — не самый последний проект
  • [UPD 2023] Эрик МакКонвилл https://github.com/emcconville/wand

Теперь Wand — это просто (уменьшенный) C API для ImageMagick «.. API — это рекомендуемый интерфейс между языком программирования C и библиотеками обработки изображений ImageMagick. В отличие от API MagickCore C, MagickWand использует только несколько непрозрачных типов. Доступны средства доступа для установки или получения важных свойств wand.» (См. домашнюю страницу проекта)

Таким образом, это уже упрощенный интерфейс, который легче поддерживать.

[UPD 2023] PS как и любое программное обеспечение API, py-wand наследует любые временные ошибки от родительского

Комментарии:

1. Основная причина, по которой я отошел от want: github.com/dahlia/wand/issues/312

2. Ftr, «исторический обзор Бенджамина Швейцера» переместился сюда: github.com/benschweizer/python-magickwand#alternatives

3. Ссылка Wand мертва.

Ответ №2:

Это сработало для меня для следующей команды для создания изображения из текста для буквы «P»:

 import subprocess

cmd = '/usr/local/bin/convert -size 30x40 xc:white -fill white -fill black -font Arial -pointsize 40 -gravity South -draw "text 0,0 'P'" /Users/fred/desktop/draw_text2.gif'

subprocess.call(cmd, shell=True)
  

Комментарии:

1. shell=True это путь к катастрофе. Вместо cmd = "a single string with all args" того, чтобы использовать cmd = ["path/to/program", "arg1", "arg2", ...] и отбрасывать shell=True навсегда.

2. Почему это проблема — проблемы с внедрением?

3. Да, инъекция является основной проблемой (руководство Python даже явно предупреждает об этом) (однако инъекция, вероятно, произойдет случайно, а не по злому умыслу). Но вы также делаете свой скрипт более зависимым от его среды / операционной системы (например, оболочки Linux имеют другие механизмы цитирования, чем Windows cmd),

Ответ №3:

Я не нашел хорошей привязки Python для ImageMagick, поэтому для использования ImageMagick в программе Python мне пришлось использовать subprocess module для перенаправления ввода / вывода.

Например, предположим, что нам нужно преобразовать PDF-файл в TIF:

 path = "/path/to/some.pdf"
cmd = ["convert", "-monochrome", "-compress", "lzw", path, "tif:-"]
fconvert = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout, stderr = fconvert.communicate()
assert fconvert.returncode == 0, stderr

# now stdout is TIF image. let's load it with OpenCV
filebytes = numpy.asarray(bytearray(stdout), dtype=numpy.uint8)
image = cv2.imdecode(filebytes, cv2.IMREAD_GRAYSCALE)
  

Здесь я tif:- сообщал утилите командной строки ImageMagick, что хочу получить изображение TIF в виде потока стандартного вывода. Аналогичным образом вы можете указать ему использовать stdin stream в качестве входных данных, указав - в качестве входного имени файла.