понедельник, 10 сентября 2012 г.

Изменение размеров фотографий из консоли


Мне потребовалось массово изменить размеры фотографий. Это необходимое зло возникшее от непонимания многих просто фотографов, которые снимают панорамы лейками с разрешением в 12мега-пикселов. Фотка получается качественной, но у меня нет такого экрана, чтобы ее рассмотреть, ибо максимум что ямогу реально увидить на своем компе, а так же на многих других фотографии не более 1 мегапиксела. Вот и возникает проблема как их массово сжать. Обычные редакторы типа Фотошоп, не в состоянии справиться с массой фотографий для подобной работы, и на помощь приходит консоль, а конкретно команды известной утилиты imagemagick , с первой из которых мы начнем наш рассказ об этой великолепной утилиты.
Здесь я не буду рассказывать о самом пакете, потому что это требует отдельного разговора и темы, а просто приведу пример конкретной реализации для моих сегодняшних нужд. Кончилось лето и много новых фоток появилось в доме вместе с разными впечатлениями привезенным с разных концов света.
Итак обычно все снимают на максимальное разрешение не задумываясь, а оно в нашей фототеки в 12 мегапикселов, отчего размеры каждой фотки получаются 4000х3000 и объемом до 4-5 мегабайт. Понятно что загружать в инет такие фотки явно не целесообразно, тем более что размер этот чаще всего избыточен для простого выкладывания фотографии в сети или отправки по электронной почте. Обычно для просмотра на экране вполне годятся фотографии с разрешением 1 мегапиксел и менее.
Создать копии в низком разрешении из набора фотографий в высоком разрешении можно, конечно, вручную, загружая каждую фотографию в графический редактор, уменьшая и сохраняя под другим именем или в другом месте. Можно это сделать и без графического редактора, с помощью программы convert из пакета ImageMagick:
$ convert -quality 90 -resize 640x640
 большое-фото.jpg уменьшенное-фото.jpg
Команда convert позволяет автоматизировать многие операции обработки графики. В данном случае она берёт файл (большое-фото.jpg), уменьшает до размера, не превышающего 640x640 (-resize 640x640), и сохраняет в формате JPEG с уровнем качества 90% (-quality 90) уменьшенное изображение в файле уменьшенное-фото.jpg.
А если файлов много? Просто и быстро это можно сделать сделать одной командой командной оболочки выполненной в каталоге с фотографиями:
$ mkdir lowres; 
    for f in *.jpg ; 
    do convert -quality 90 -resize 640x640 
      "$f" "lowres/${f%.jpg}-640.jpg"; 
    echo "$f"; 
    done; 
    echo "OK"
Расмотрим эту строчку по порядку. Сначала создается подкаталог lowres в текущем каталоге (mkdir lowres); далее для всех файлов с разрешением .jpg (for f in *.jpg ; do ... ; done) вызывает команду конвертации (convert), которая сохраняет уменьшенные изображения в подкаталоге lowres под именем с окончанием -640.jpg. Так, если в исходном каталоге были изображения с именами мама.jpg, папа.jpg, я.jpg, то после выполнения указанной команды должен появиться подкаталог lowres/ с изображениями мама-640.jpg, папа-640.jpg, я-640.jpg. Изменённые имена файлов позволят не спутать их с исходными изображениями в высоком разрешении.
Набор команд между do и done повторяется несколько раз, для каждого файла подходящего по шаблону *.jpg. Имя обрабатываемого файла при этом хранится в "переменной" f. Запись $f позволяет получить это имя файла, а ${f%.jpg} отсекает (%) от имени файла окончание .jpg. Обратите внимание, что имена файлов берутся в двойные кавычки: "$f", "${f%.jpg}-640.jpg" -- это позволяет обрабатвать также имена файлов содержащие пробелы.
Конструкцию for f in шаблон ; do что сделать с каждым файлом ; done удобно использовать и для многих других целей. Например, для автоматического переименования или копирования файлов. Так же командой echo (echo "$f";) выводится трасировка действия в цикле ввиде отображения имен исходных файлови после его окончания выводится сообщение ОК, об окончании всего пакета.
Здесь специально пакет выполняется в виде командной строки. По уму надо бы было сделать командный файл Bash! Но это уже будушее а пока я делаю так и доволен.