Наши партнеры

UnixForum





Библиотека сайта rus-linux.net

Обработка графики в командной строке

Оригинал: Graphics from the command line
Автор: Michael Still
Дата публикации: 16 июля 2003 года
Перевод: А. Кривошей
Дата публикации перевода: 5 декабря 2012 г.

В этой статье описывается, как обрабатывать изображения в командной строке. Я занимаюсь этим достаточно часто, так как моя коллекция фотографий насчитывает несколько тысяч штук. Утилиты командной строки особенно полезны для веб-разработчиков или администраторов, которые часто занимаются пакетной обработкой большого количества изображений, так как разработчик может просто интегрировать их в свои скрипты. Но даже если вы занимаетесь этим от случая к случаю, утилиты командной строки помогут вам сэкономить время.
Инструменты командной строки, описываемые в этой статье, являются частью великолепного пакета ImageMagick, который доступен практически во всех дистрибутивах Linux, а также в сети (см. ресурсы). Также к функциям ImageMagick можно получить доступ с помощью C, C++, Perl, Python, Java и некоторых других языков программирования.

Как работает ImageMagick

ImageMagick служит оберткой для набора различных графических библиотек, включающего libtiff и libpng. В терминологии ImageMagick это вызываемые делегаты. Это является одной из причин, почему ImageMagick не так быстр, как мог бы быть. Он написан таким образом, что может взаимодействовать с библиотеками несколькими способами. Необходимо отместить, что все описанное в этой статье можно выполнять различными способами. Я описываю методы, которые я использовал и которые у меня работали. Это не значит, что другие утилиты в этом случае не будут работать, это всего лишь значит, что мне было удобно работать так, как это описано.
В статье специфические проблемы обсуждаются на конкретных примерах, но описанные концепции должны быть применимы и к другим подобным проблемам.

Создание миниатюр

Первое, что я делаю со своей коллекцией изображений - создаю миниатюры. Также я хотел создать уменьшенные версии изображений для размещения на сайте, так как вряд ли многие захотят открывать 2-х мегапиксельные фотографии моего сына.
Я использовал утилиту convert, которая входит в состав ImageMagick. Convert очень хороша. Помимо уменьшения размера изображений она может размывать их, конвертировать из одного формата в другой, обрезать, очищать от мусора, рисовать рамки, делать зеркальное отображение, и многое другое. Чтобы познакомиться со всеми ее возможностями и опциями командной строки, почитайте man-страницу. Многие более интересные визуальные эффекты, получаемые с помощью convert, будут описаны ниже.
Итак, допустим, что я хочу сделать миниатюру этой довольно красивой фотографии розы:

Изображение розы

Чтобы изменить размер изображения с помощью convert, просто используйте опцию командной строки -sample. Например, мне нужна миниатюра размером 80 x 40 пикселей. Тогда команда будет выглядеть следующим образом:

$ convert -sample 80x40 input.jpg output.jpg

Полученная миниатюра будет выглядеть так:

Первая попытка создания миниатюры

ImageMagick при преобразовании автоматически сохраняет соотношение сторон первоначального изображения. Это значит, что реальный размер созданной нами миниатюры составит 53 на 40 вместо 80 на 40.
Вместо пикселей размер конвертированного изображения можно указывать в процентах от исходного размера. Это может быть полезно, если вы не знаете размера исходного изображения, или если вам не столь важен точный размер картинки. Ниже приведен пример использования процентов:

$ convert -sample 25%x25% input.jpg output.jpg

Теперь мы получим такую миниатюру:

Вторая попытка создания миниатюры

С помощью этой команды можно создать миниатюры всех изображений в директории. Так как эта статья не посвящена написанию скриптов, я просто покажу вам пример скрипта для создания миниатюр всех JPEG в текущей директории:

Листинг 1. Создание миниатюр всех JPEG в текущей директории

for img in `ls *.jpg`
do
  convert -sample 25%x25% $img thumb-$img
done

Этот скрипт генерирует серию миниатюр размером 25% от размера исходного изображения с именем файла, которое создается путем добавления префикса thumb- к имени файла исходного изображения.

Получение информации о файле изображения

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

$ tiffinfo sample.tif

Листинг 2. Простой вывод tiffinfo

TIFF Directory at offset 0x146
  Image Width: 352 Image Length: 288
  Bits/Sample: 8
  Compression Scheme: Deflate
  Photometric Interpretation: RGB color
  Samples/Pixel: 3
  Planar Configuration: single image plane

Это не самый исчерпывающий пример использования tiffinfo, но, как вы можете видеть, она возвращает достаточное количество информации. Похожая утилита pnginfo возвращает информацию о файлах PNG.

$ pnginfo sample.png

Листинг 3. Простой вывод pnginfo

$ sample.png...
  Image Width: 640 Image Length: 480
  Bitdepth (Bits/Sample): 8
  Channels (Samples/Pixel): 3
  Pixel depth (Pixel Depth): 24
  Colour Type (Photometric Interpretation): RGB 
  Image filter: Single row per byte filter 
  Interlacing: No interlacing 
  Compression Scheme: Deflate method 8, 32k window
  Resolution: 0, 0 (unit unknown)
  FillOrder: msb-to-lsb
  Byte Order: Network (Big Endian)
  Number of text strings: 0 of 0

Я не знаю, есть ли аналогичные утилиты для других графических форматов, таких как BMP, GIF и JPEG. Тем не менее, и в этом случае на помощь приходит ImageMagick с утилитой под названием identify.

$ identify -verbose sample.png

Листинг 4. Простой вывод identify

Image: sample.png
  Format: PNG (Portable Network Graphics)
  Geometry: 640x480
  Class: DirectClass
  Type: true color
  Depth: 8 bits-per-pixel component
  Colors: 142360
  Filesize: 555.6k
  Interlace: None
  Background Color: grey100
  Border Color: #DFDFDF
  Matte Color: grey74
  Dispose: Undefined
  Iterations: 0
  Compression: Zip
  signature: 361fe70ae623ef6f1fca44e0d29d157c2d701039fcf0f8625862925d881e13a4
  Tainted: False
  User Time: 0.190u
  Elapsed Time: 0:01

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

identify также имеет флаг командной строки -format, который позволяет задать вывод только нужной вам информации. Например, если вас интересует только размер изображения, вы можете использовать команду вида:

$ identify -format "%wx%h" sample.png

Вывод этой команды:

$ 640x480

Здесь %w значит ширину изображения, а %h - высоту. Для получения более подробной информации о форматировании вывода identify можно узнать, прочитав man-страницу утилиты.

Вращение изображений

Другая часто встречающаяся задача - поворот изображений. Например, многие сделанные цифровой камерой фотографии требуется повернуть на 90 градусов, чтобы нормально просматривать их в портретном режиме. Моя камера не делает этого автоматически, поэтому я написал скрипт, который запускаю после копирования фотографий с камеры.
Например, это фото я сделал во время своей последней в поездки в Port Arthur в Тасмании:

Port Arthur

Чтобы повернуть изображение, мы снова используем команду convert:

$ convert -rotate 90 input.jpg output.jpg

Теперь фотография выглядит так:

Port Arthur после поворота

Заметьте, что аргумент опции -rotate - это число градусов, на которое нужно повернуть изображение по часовой стрелке. Для повора против часовой стрелки вводится число градусов со знаком минус.

Конвертирование изображений

Команда convert также используется для конвертирования файлов изображений. Под конвертированием здесь подразумевается как изменение формата фотографии, например из JPEG в PNG, так и преобразование цветной фотографии в черно-белую, сглаживание и другие подобные операции.
convert определяет форматы исходного и преобразованного изображений, основываясь на расширениях файлов. Итак, чтобы конвертировать JPEG в PNG, используйте следующую команду:

$ convert input.jpg output.png

ImageMagick в настоящее время поддерживает 89 форматов изображений.

Добавление текстовых подписей к изображению

Иногда бывает нужно добавить тестовую подпись к изображению. Например, представьте, что в вашей компании используется единый шаблон для визитных карточек, и нужно подставить данные конкретного сотрудника перед отправкой карточки на печать. Другой пример - создание сертификатов для пользователей, которые проходят онлайн-курсы на вашем веб-сайте.

Давайте начнем с этого фото:

Фото с Floriade 2002

Вы можете подписать изображение с помощью следующей команды:

$ convert -font helvetica -fill white -pointsize 36 \
-draw 'text 10,50 "Floriade 2002, Canberra, Australia"' \
floriade.jpg comment.jpg

Результат:

Подписанное фото с Floriade 2002

Это, наверное, самая сложная для понимания команда из приведенных в этой статье, поэтому она требует некоторых пояснений.
-font helvetica задает, что подпись будет сделана шрифтом Helvetica. Также возможно указать здесь подпись к файлу шрифта. В приведенном ниже примере я помечаю фото, чтобы его не использовали на других веб-сайтах без разрешения, при этом использую шрифт, который находится в нестандартном месте:

$ convert -font fonts/1900805.ttf -fill white -pointsize 36 \
-draw 'text 10,475 "stillhq.com"' \
floriade.jpg stillhq.jpg

Результат:

Помеченное изображение

-fill white - задает белый цвет шрифта вместо стандартного черного.
-pointsize 36 задает размер шрифта в точках. В данном случа 72 точки на дюйм.
-draw 'text 10,50 "..."' - это набор команд для рисования, в данном случае - начальная позиция текста 10, 50; текст заключен в двойные кавычки. Одинарные кавычки используются в связи с тем, что если текст содержит более одного слова, он должен быть заключен в двойные кавычки. Кроме того, двойные кавычки не могут быть вложены в другие двойные кавычки.

Другие, более артистичные преобразования

convert способен также выполнять быстрые художественные преобразования. Я продемонстрирую наиболее интересные из них. О других можно прочитать на сайте ImageMagick. Для демонстрации я буду использовать следующее изображение:

Uluru на закате

Charcoal

Эффект charcoal имитирует рисование углем.

$ convert -charcoal 2 input.jpg output.jpg

Результат:

Uluru на рассвете после применения эффекта charcoal

Увеличение магнитуды аргумента опции -charcoal усиливает эффект, но при этом обработка изображения требует больше времени. Ниже пример с увеличенным значением:

$ convert -charcoal 10 input.jpg output.jpg

И получаем:

Uluru на рассвете после применения усиленного эффекта charcoal

Если вы хотите посмотреть, как будет выглядеть максимально усиленный эффект charcoal, попробуйте:

$ convert -charcoal 200 input.jpg output.jpg

Получаем вот это:

Uluru на рассвете после применения чрезмерно усиленного эффекта charcoal

Сolorize

Сolorize - это процесс смешивания цвета каждого пикселя с заданным цветом. Аргумент обозначает цвет, с которым производится смешивание. Он может быть задан в виде одного значения (это значение используется для красного, зеленого и синего цветов), или в виде трех значений. Максимальное значение - 255.

$ convert -colorize 255 input.jpg output.jpg

Uluru теперь выглядит так:

Uluru на закате после применения эффекта colorize

Implode

Эффект implode моделирует втягивание центра вашего изображения в виртуальную черную дыру. Аргумент задает степень воздействия эффекта.

$ convert -implode 4 input.jpg output.jpg

Uluru теперь выглядит так:

Uluru на закате после применения эффекта implode

Solarize

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

$ convert -solarize 42 input.jpg output.jpg

Теперь наше фото будет выглядеть так:

Uluru на закате после применения эффекта solarizing

Spread

Spread перемещает пиксели изображения в случайном порядке. Аргумент задает размер области вокруг пикселя, в пределах которой выбирается его новое местоположение, то есть насколько размазанным будет изображение.

$ convert -spread 5 input.jpg output.jpg

Ниже Uluru после размазывания:

Uluru на закате после применения эффекта spread

Несколько команд в одном вызове ImageMagick

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

$ convert -sample 25%x25% -spread 4 \ -charcoal 4 input.jpg output.jpg

Результат:

Uluru после применения цепочки эффектов

Хитрости и подсказки

Есть несколько моментов, о которых нужно помнить, перед тем, как вы начнете работать со своими фото. Во-первых, вы должны определиться с форматом, в котором вы собираетесь хранить изображения, чтобы не оказаться в ситуации, когда у вас будет куча фотографий в формате, который вас не будет больше устраивать.
JPEG-сжатие хорошо подходит для больших изоборажений, таких как фотографии. Однако, это сжатие происходит с потерей данных, поэтому JPEG плохо подходит для текста, который должен оставаться читаемым. Кроме того, необходимо учитывать, что потери накапливаются при каждом изменении изображения. Для цветных изображений, если вы не хотите, чтобы при каждом редактировании накапливались потери, хорошо подходит PNG.
Вы также должны помнить, что большинство манипуляций, показанных в данной статье, невозможно отменить. Например, возьмем фотографию, сделаем миниатюру, а затем увеличим ее до размера исходной фотографии. Чтобы сэкономить место, я пропускаю промежуточные шаги и привожу сразу конечный результат.

Водопад

Итак, мы объединили уменьшение с увеличением:

$ convert -sample 10% -sample 1000% input.jpg output.jpg

В результате получили следующую картинку:

Водопад после обработки

Достаточно трудно узнать водопад на этой фотографии.

Заключение

В этой статье мы обсудили несколько интересных вещей, которые позволяет делать ImageMagick при обработке изображений в командной строке. Описанные здесь инструменты не решат всех проблем, но позволят сэкономить время при выполнении рутинных, наиболее часто встречающихся операций.