К основному контенту

Обработка изображений с ImageMagick

ImageMagick (http://www.imagemagick.org) — набор утилит для создания, редактирования, конвертирования и просмотра растровых изображений. Графический режим необходим только для просмотра. Для остальных действий над изображениями достаточно консоли. То есть налицо два отличия от привычных редакторов растровых изображений (вроде GIMP или Krita):
  • использование набора утилит вместо одной программы
  • для операций над изображениями не требуется GUI.

Очевидно, что таким инструментом вряд ли будут пользоваться художники, фотографы или дизайнеры. Чтобы разобраться для кого предназначен этот набор, предлагаю ознакомиться с предоставляемыми возможностями.

Что умеет ImageMagick?


Чтобы ответить на поставленный вопрос я перечислю входящие в набор утилиты, напишу какой функционал предоставляет каждая из них и, конечно же, приведу примеры использования.
identify — информационная утилита, воспользовавшись которой можно узнать формат изображения и множество других его свойств (например, высоту, ширину, количество используемых цветов). Также она предоставляет некоторую информацию о самом ImageMagick (поддерживаемые форматы, подключенные модули кодирования/декодирования изображения, флаги сборки, таблица цветов с соответствующими им значениями в RGB-системе). К тому же эта утилита умеет форматировать свой вывод. Например, чтобы для всех изображений в папке вывести имя файла и соответствующие ему ширину и высоту, скомандуем:
identify -format "%f %w %h" somedir/*

import — утилита, при помощи которой можно получить снимки всего экрана или указанного окна. Для получения снимка всего экрана выполним команду:
import -window root screen.ps

convert, mogrify — две утилиты со схожей функциональностью. Главное их отличие состоит в том, что первая на основе существующих изображений создает их модифицированные версии, а вторая модифицирует непосредственно сами изображения. Умеют эти утилиты немало: изменять размер изображения, обрезать его, удалять пятна, добавлять дрожание, размытость, зеркально отображать, рисовать поверх изображения, соединять несколько в одно, выполнять повторную выборку изображения и многое другое. Приведу несколько примеров:
convert test*.jpg -resize 50% test.png (изменение размера)

convert test[1-5].jpg -mattecolor SlateBlue -frame 9x9+3+3 framed_test.jpg (добавление рамки заданного цвета)

convert test.jpg -thumbnail 200x135 thumbnail_test.jpg (создание миниатюры)
compare — используйте эту утилиту, чтобы определить разницу между исходным изображением и его модификацией. Имеется несколько метрик, по которым проводится сравнение. Выбрать нужную вам можно, воспользовавшись опцией -metric. Список допустимых значений этого параметра можно узнать, выполнив команду compare -list metric. Приведу пример:
compare -metric AE -fuzz 3% test.jpg test_mod.jpg compare_fuzz.jpg

Разберем его. Используется метрика AE = Absolute Error (общее число различных пикселей). Маленькое значение параметра fuzz указывает, что незначительными различиями можно пренебречь. Указаны сравниваемые изображения и последний параметр задает файл результата сравнения. Чтобы было понятно, что получается в результате приведу здесь пример сравниваемых изображений и результат выполнения команды (в результирующем изображении красным цветом обозначены отличающиеся пикселы).
test.jpg

test_mod.jpg

compare_fuzz.jpg

composite — утилита наложения одного изображения на другое. Композиционные методы поделены на четыре группы:
  1. методы альфа-смешения (clear, src, dst, src-over, dst-over, src-in, dst-in, src-out, dst-out, src-atop, dst-atop, xor);
  2. методы математической композиции (multiply, screen, plus, add, minus, subtract, difference, exclusion, darken, lighten);
  3. методы композиции освещения (linear-dodge, linear-burn, color-dodge, color-burn, overlay, hard-light, linear-light, soft-light, pegtop-light, vivid-light, pin-light);
  4. специальные методы композиции (copy-*, change-mask).
Пример использования утилиты для добавления водяного знака к исходному изображению:
composite -dissolve 40% -gravity center watermark.gif test.png res.png

montage — эта утилита используется для создания составного изображения из нескольких отдельных.
montage test1.jpg test2.jpg res.jpg

stream — утилита для работы с изображением, как с потоком пикселей. Она пригодится при обработке больших изображений
stream -map i -storage-type double -extract 100x100+30+40 image.tif gray.raw

В этом примере мы извлекаем область 100x100 в оттенках серого из изображения в формате TIFF.
animate — утилита для анимации последовательности изображений.
animate *.jpg

display — утилита для просмотра изображений и их последовательностей. Пример использования:
display test.jpg

Но эта утилита еще полезна и тем, что помимо окна просмотра, предоставляет панель со множеством действий по обработке изображения, доступных из консоли. Можно сказать, что эта утилита является демонстрацией возможностей других утилит этого набора. Выглядит это так:

conjure — утилита, позволяющая выполнять скрипты с определенными пользователем действиями по обработке изображений. Скрипты пишутся на MSL (Magick Scripting Language) — диалекте XML. Теги — это действия над изображениями (чтение файла, обработка изображения, получение его свойств, запись в файл и многое другое). Пример скрипта:
  <?xml version="1.0" encoding="UTF-8"?>
  <group>
    <image id="family">
      <read filename="peoples.gif"/>
      <resize geometry="300x300"/>
    </image>
    <image id="palm-trees">
      <read filename="trees.gif"/>
      <resize geometry="300x100"/>
    </image>
    <image>
      <read filename="beach.jpg"/>
      <composite image="peoples" geometry="+30+40"/>
      <composite image="trees" geometry="+320+90"/>
    </image>
    <write filename="vacation.png"/>
  </group>

К сожалению, разработчики не уделяют достаточно внимания MSL, в частности, документированию его возможностей. Впрочем можно задать последовательность действий в скрипте командной оболочки. Если же этой возможности окажется недостаточно, вы можете написать собственную программу, воспользовавшись предоставляемым API. Имеются привязки к наиболее используемым языкам программирования (C, C++, Java, PHP, Python, Perl и другие). При чем для C имеется два API: MagickCore API (достаточно низкоуровневый) и MagickWand API (рекомендованный для широкого использования).

Информационная поддержка ImageMagick


Итак, если вы решили использовать ImageMagick, вам скорее всего понадобится дополнительная информация. Здесь я расскажу об основных её источниках. Это в первую очередь man страницы (для каждой утилиты отдельная страница), в которых есть ссылки на страницы документации на сайте. Кроме того, по ссылке http://www.imagemagick.org/Usage/ вы найдете немалую коллекцию примеров использования ImageMagick. Коллекция разделена на 2 части: базовые техники и решение реальных задач.
Если вам нужна информация по API, ищите ее на http://www.imagemagick.org/script/api.php. Основная информация дана для языков C, C++ и Perl. И именно на нее следует ориентироваться.
Если при чтении документации у вас возникают вопросы, вы можете задать их на форуме (http://www.imagemagick.org/discourse-server/).

В итоге


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

Комментарии

VL написал(а)…
" Также вы можете использовать богатые возможности этого набора при разработке своего приложения."
Для разработки графических редакторов, особенно, - узкоспециализированных можно использовать эти утилиты как готовые модули - положил в их и их скрипты в папочку, приделал их автообновление, приделал несколько кнопок или команд и окошко для просмотра результатов в папке вывода, - запаковал в архив - вот и готов например, редактор по названием "Красноглазики не пройдут" (спец-й редактор для борьбы с эффектом красных глаз).

Популярные сообщения из этого блога

Одно приложение, несколько баз данных

Рецепт от Spring Boot Некоторое время назад мне довелось писать агрегатор информации, разбросанной по нескольким базам данных с разными схемами. Для реализации был выбран Spring Boot. Ну, потому что модный и судя по примерам существенно упрощает жизнь за счет умной автоконфигурации. В этой статье я опишу, что же необходимо сконфигурировать и как, в случае, если вы отошли от стандартного сценария. Первым делом, необходимо прописать настройки доступа к каждой из баз. Например, вот так: Следующим шагом создадим отдельный класс конфигурации (для удобства), в котором определим dataSources: Обратите внимание, как просто получить настройки с помощью @ConfigurationProperties. Правда, пришлось ввести вспомогательный класс BaseDataSourceProperties — наследник DataSourceProperties, в котором область видимости метода getDriverClassName расширена до public. И осталось совсем немного — сконфигурировать JPA-репозитории. Насчет немного я, конечно, пошутил :) В этой части предстоит больше

Может ли TreeSet содержать дубликаты?

Не спешите давать ответ, а лучше запустите код, приведенный ниже. Возможно вы подумаете, что это надуманный пример, но это лишь немного упрощенная версия того кода, с которым мне пришлось столкнуться на практике. Для начала о проблеме, которую был призван решить этот код. В списке объектов надо было оставить объекты с различными именами, причем неважно какой объект из всего набора с таким же именем останется. Сразу же уточню, что на практике в проекте используется Java 7 и класс объектов, добавляемых в TreeSet, не вложен в какой-либо другой, а приведенный здесь вариант использован для краткости. Может возникнуть вопрос почему выбрано именно такое решение. Давайте разберемся, чтобы не повторять ошибку. Первое, что приходит в голову, когда из списка надо удалить дубликаты, - использовать Set. В данной ситуации HashSet не подходит, потому что он использует equals метод для сравнения и отсеивания дубликатов. Но наш программист не сдаётся и вспоминает, что есть же еще TreeSet, в докум