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

UnixForum





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

Обработка изображений с помощью утилит из пакета ImageMagick

Оригинал: Image Manipulation with ImageMagick
Автор: Dave Taylor
Дата публикации: 17 апреля 2015 г.
Перевод: А.Панин
Дата перевода: 4 сентября 2015 г.

Обработка изображений с помощью утилит из пакета ImageMagick

Я потратил достаточно много времени на написание для своей колонки статей, посвященных обработке и анализу текста, предполагая, что в том случае, если вы работаете с интерфейсом командной строки системы, вы наверняка работаете с текстовыми данными. Это не всегда так и в том случае, если вы работаете с изображениями любых форматов - JPEG, PNG, GIF или каких либо других - следует помнить о существовании свободно распространяемого пакета утилит для обработки изображений, позволяющих выполнять удивительные операции непосредственно при работе с интерфейсом командной строки операционной системы и, следовательно, в рамках сценариев командной оболочки.

Я говорю о пакете утилит ImageMagick, являющемся набором программ, который совершенствовался и расширялся в течение многих лет и на данный момент также включает в свой состав мощные интерфейсы для языков программирования Perl и Ruby. Но зачем они нам! У нас нет причин связываться с языками программирования Perl или Ruby. Лучше поработаем с нашими проверенными командами командной оболочки.

Вы можете найти бинарные файлы и архивы исходного кода пакета ImageMagick на ресурсе http://www.imagemagick.org и, как обычно, я рекомендую вам загрузить архив исходного кода и скомпилировать его на своей системе при наличии такой возможности. Это гораздо надежнее, чем надеяться на то, что скомпилированные кем-либо версии бинарных файлов будут оптимизированы для работы с вашим аппаратным обеспечением.

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

Поиск изображений с неоптимизированными разрешениями

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

$ file wp-content.tar.gz
wp-content.tar.gz: gzip compressed data, from Unix

Но данная утилита практически бесполезна для определения параметров изображений:

$ file pvp.jpg
pvp.jpg: JPEG image data, EXIF standard

А как насчет размера изображения? И вообще какой-либо полезной информации? Черт побери.

Воспользуемся утилитой identify из пакета ImageMagick:

$ identify pvp.jpg
pvp.jpg JPEG 970x311 DirectClass 114kb 0.010u 0:01

Ах... значит данное изображение имеет размер (утилита из рассматриваемого пакета использует аналогичный параметр "геометрия" изображения ("geometry")), равный 970x311. Это полезная информация.

Не хотите получить дополнительную информацию об этом изображении? Параметр -verbose позволяет вывести ошеломляющий объем информации об изображении:

$ identify -verbose pvp.jpg
Image: pvp.jpg
  Format: JPEG (Joint Photographic Experts Group JFIF format)
  Geometry: 970x311
  Class: DirectClass
  Colorspace: RGB
  Type: TrueColor
  Depth: 8 bits
  Endianess: Undefined
  Channel depth:
    Red: 8-bits
   Green: 8-bits
    Blue: 8-bits
  Channel statistics:
    Red:
      Min: 0
      Max: 255
      Mean: 180.72
      Standard deviation: 74.2122
    Green:
      Min: 0
      Max: 255
      Mean: 168.593
      Standard deviation: 76.0343
    Blue:
      Min: 0
      Max: 255
      Mean: 169.459
      Standard deviation: 77.244
  Colors: 21864
  Rendering-intent: Undefined
  Resolution: 72x72
  Units: Undefined
  Filesize: 114kb
  Interlace: None
  Background Color: white
  Border Color: #DFDFDF
  Matte Color: grey74
  Dispose: Undefined
  Iterations: 0
  Compression: JPEG
  Orientation: Undefined
  JPEG-Quality: 94
  JPEG-Colorspace: 2
  JPEG-Sampling-factors: 1x1,1x1,1x1
  signature: bc8a6a698ca35fd8feab71452423386ff98b1fb7b5ec ...
  Profile-xmp: 811 bytes
  Profile-exif: 22 bytes
    unknown
  Profile-app12: 15 bytes
  Tainted: False
  User Time: 0.020u
  Elapsed Time: 0:01

Откровенно говоря, размеры изображения и разрешение являются наиболее важными параметрами из данного удивительно длинного вывода.

С помощью небольших усилий вы можете извлечь значения этих параметров:

$ identify -verbose pvp.jpg | grep -E '(Resolution:|Geometry:)'
  Geometry: 970x311
  Resolution: 72x72

Теперь представьте, что вы работаете над веб-сайтом и хотите убедиться в том, что разрешение ни одного из изображений не превышает стандартного разрешения экрана, равного 72 точки на дюйм. Более высокие разрешения, полезные при печати документов, будут являться излишними, так как изображение с разрешением в 300 точек на дюйм будет выглядеть на экране аналогично изображению с меньшим расширением - при этом оно будет загружаться медленнее.

Ниже приведен пример кода для идентификации изображений с некорректными разрешениями из директории:

#!/bin/sh
identify=/usr/bin/identify
# проверка соответствия разрешений всех изображений разрешению 72x72.
for filename
do
  resolution=$($identify -verbose $filename | \
     grep -i "Resolution:" | grep -v 72x72)
  if [ ! -z "$resolution" ] ; then
    echo "Внимание: Изображение $filename имеет отличное значение параметра $resolution"
  fi
done
exit 0

После того, как я выполнил данный сценарий в директории для изображений моей системы, заполненной изображениями формата JPEG с моего веб-сайта http://www.AskDaveTaylor.com, я получил следующий вывод:

$ checkres.sh *.jpg
Внимание: Изображение auction-seller-img1.jpg имеет отличное значение параметра Resolution: 75x75
Внимание: Изображение auction-seller-img2.jpg имеет отличное значение параметра Resolution: 75x75
Внимание: Изображение browsing-the-photo-folder.jpg имеет отличное значение параметра Resolution: 96x96
Внимание: Изображение brushed-metal.jpg имеет отличное значение параметра Resolution: 300x300
...

Вот так сюрприз! Я и не догадывался о том, что использую изображения с разрешением 300x300 и другими нестандартными разрешениями. Следовательно, простым способом ускорения загрузки моего сайта является уменьшение разрешения данных изображений до стандартного разрешения, равного 72 точки на дюйм. Эта операция может быть выполнена с помощью другой утилиты из состава пакета ImageMagick, но давайте оставим это для следующей статьи.

Работа с размерами изображений

Так как я разрабатываю множество сценариев для сбора изображений и другого содержимого веб-сайтов для личного использования (не связанного с публичной демонстрацией), я также считаю чертовски полезным сценарий командной оболочки для определения размера только что полученного изображения.

Если вы предположили, что в данном случае ключевым элементом также будет утилита identify, вы правы. Фактически, данный способ является простым способом получения значений высоты и ширины изображения:

height=$(identify $image | cut -d\   -f3 | cut -dx -f1)
width=$(identify $image | cut -d\   -f3 | cut -dx -f2)

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

Теперь гораздо проще создавать высококачественные страницы HTML, к примеру, выключая изображения с указанием их корректных размеров.

echo "<img src=$image height=$height width=$width>"

Полезное свойство веб-браузеров заключается в автоматическом масштабировании изображений, поэтому вы можете указать отличные от реальных размеров (простите, следует говорить "реальной геометрии") значения высоты и ширины изображения, после чего веб-браузер осуществит автоматическое масштабирование изображения.

Это означает, что в том случае, если вы хотите включить изображение с именем pvp.jpg в состав автоматически сгенерированной страницы, но посчитаете, что ширина в 970 пикселей слишком велика, вы можете подключить это изображение с помощью следующего тэга:

<img src=pvp.jpg height=207 width=646>

а веб-браузер - будь то Chrome, Safari или даже MS IE - осуществит его масштабирование соответствующим образом.

Расчет минимального размера достаточно прост благодаря утилите bc, еще одной недооцененной утилите Linux. Вся последовательность команд для изменения размера изображений до 66% от начального размера может выглядеть следующим образом:

#!/bin/sh
identify=/usr/bin/identify
scale=0.666
image=$1   # здесь следует добавить код для проверки корректности имени изображения

height=$($identify $image | cut -d\   -f3 | cut -dx -f1)
width=$($identify $image | cut -d\   -f3 | cut -dx -f2)
newwidth="$(echo $width \* $scale | bc | cut -d. -f1)"
newheight="$(echo $height \* $scale | bc | cut -d. -f1)"
echo "<img src=$image height=$newheight width=$newwidth>"
exit 0

На практике сценарий может использоваться следующим образом:

$ scaledown.sh pvp.jpg
<img src=pvp.jpg height=646 width=207>

И это достаточно просто!

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

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

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