IT Notes

ImageMagick: Обрезаем изображения в консоли

Введение

Перед нами следующее изображение:

search

Мы хотим вырезать то, что находится внутри прямоугольной области диалогового окна поиска файла. Делать мы это будем с помощью консольной утилиты ImageMagick. Вы можете установить ее на большинстве платформ. Например, под Linux она наверняка найдется в репозитории вашего дистрибутива, а под Windows устанавливается в рамках пакета cygwin.

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

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

Следующая команда вырезает нужную область из исходного изображения:

convert img.png -crop 655x383+79+49 +repage out.png

В результате выполнения команды в файле out.png окажется следующее:

Разберем аргументы команды convert, входящей в состав ImageMagick:

  1. Первым ей передается путь к файлу входного изображения;
  2. Далее следует аргумент -crop, который говорит о том, что мы хотим вырезать область из изображения. Этот параметр сопровождается несколькими значениями. В нашем случае: 655x383+79+49, где 655x383 - высота и ширина вырезаемой области, а +79+49 - отступы от левого верхнего угла по горизонтали и вертикали, которые указывают на левый верхний пиксель вырезаемой области. Определить эти значения можно в любом графическом редакторе. Например, в GIMP их легко найти с помощью прямоугольного выделения;
  3. Ключ +repage используется, чтобы предотвратить сохранение исходной геометрии изображения для некоторых форматов. Если его опустить, то выходное изображение сохранит размеры исходного, а вырезанная область будет расположена в нем на старой позиции со смещением относительно левого верхнего угла;
  4. И наконец последний параметр - out.png. Он определяет путь выходного изображения, которое получилось в результате вырезания.

Но все это мы могли сделать с помощью того же GIMP, поэтому рассмотрим более интересный пример.

Делаем паззл из изображения

Создадим простой скрипт split_image.sh, который нарезает изображение на равные прямоугольные области:

#!/bin/sh

INPUT=$1
COUNT=$2
OUTPUT=$3

BASE_NAME=$( basename "$INPUT" )
EXT=${BASE_NAME##*.}

SIZE=$( identify "$INPUT" | awk '{ print $3 }' )
WIDTH=$( echo $SIZE | awk -F'x' '{ print $1 }' )
HEIGHT=$( echo $SIZE | awk -F'x' '{ print $2 }' )

BLOCK_WIDTH=$( expr $WIDTH / $COUNT )
BLOCK_HEIGHT=$( expr $HEIGHT / $COUNT )

WIDTH=$( expr $WIDTH - $BLOCK_WIDTH )
HEIGHT=$( expr $HEIGHT - $BLOCK_HEIGHT )

X=0
Y=0
I=0

while [[ $X -le $WIDTH ]]; do
    while [[ $Y -le $HEIGHT ]]; do
        OUTPUT_FILE_NAME=$( printf '%s_%03d.%s' "$OUTPUT" "$I" "$EXT" )
        convert "$INPUT" -crop "$BLOCK_WIDTH"x"$BLOCK_HEIGHT"+"$X"+"$Y" +repage "$OUTPUT_FILE_NAME"
        Y=$( expr $Y + $BLOCK_HEIGHT )
        I=$( expr $I + 1 )
    done
    X=$( expr $X + $BLOCK_WIDTH )
    Y=0
done

На вход он принимает 3 параметра: имя входного изображения INPUT, количество частей COUNT, на которые должно быть разбито изображение, и базовое имя выходных изображений OUTPUT. Следует отметить, что количество частей определяет то, сколько условных разрезов будет проведено по горизонтали и вертикали. Размер входного изображения определяется с помощью команды identify, которая также входит в состав ImageMagick. Сама нарезка осуществляется в двойном цикле while.

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

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

./split_image.sh img.png 3 out

На выходе мы получим 9 изображений вида out_00X.png, которые образуют паззл из исходного изображения.

Пакетное нарезание большого количества изображений

Без особых сложностей реализуется скрипт batch_cut.sh для пакетной нарезки целого каталога с изображениями, если область для вырезания в каждом из них имеет одинаковый размер и позицию:

#!/bin/sh

IN_FOLDER=$1
WIDTH=$2
HEIGHT=$3
LEFT_X=$4
LEFT_Y=$5
OUT_FOLDER=$6

if [[ ! -d "$OUT_FOLDER" ]]; then
    mkdir -p "$OUT_FOLDER"
fi

for IMAGE in $( ls -1 "$IN_FOLDER" ); do
    convert "$IN_FOLDER/$IMAGE" -crop "$WIDTH"x"$HEIGHT"+"$LEFT_X"+"$LEFT_Y" +repage "$OUT_FOLDER/$IMAGE"
done

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

Воспользоваться им можно так:

./batch_cut.sh IN/ 376 374 96 59 OUT/

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

Заключение

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

Похожие публикации