Pull to refresh

Пакетная обработка изображений в GIMP

Reading time 4 min
Views 27K
Время от времени возникает необходимость выложить в сеть фотоальбом или пакет отсканированных документов. В большинстве случаев изображения предварительно нужно уменьшить, а иногда и произвести дополнительную обработку, добавить надписи. И вот наступил момент, когда выполнять однотипные операции стало совсем лениво. Вспоминаем про замечательные средства автоматизации в замечательном и бесплатном редакторе GIMP.

Допустим, у нас есть куча фотографий разных размеров, с разным соотношением сторон и сохранённых в разных форматах. В общем, тяжёлый случай. Нам нужно весь этот зоопарк выровнять по размерам, учитывая пропорции, и сохранить в JPEG с заданным качеством. Да, и пусть нам иногда захочется задавать размеры не в пикселях, а процентах. Ну и пусть уже тогда захочется файлы выбирать по маске, типа «C:\images\img_01*.jpg».

Садимся, и калякаем на Script-Fu (доступный по умолчанию в GIMP, язык) свой первый сценарий:

(define (batch-resize pattern size quality)
  (let* ((filelist (cadr (file-glob pattern 1)))
      (len (if (string? size) (string-length size) 0))
      (rate (if (and (> len 0) (char=? #\% (string-ref size (- len 1)))) (/ (string->number (substring size 0 (- len 1))) 100) 0))
      (size (if (> rate 0) 0 (if (> len 0) (string->number size) size)))
    )
    (while (not (null? filelist))
      (let* ((filename (car filelist))
          (image (car (gimp-file-load RUN-NONINTERACTIVE filename filename)))
          (drawable (car (gimp-image-get-active-layer image)))
          (old-width (car (gimp-image-width image)))
          (old-height (car (gimp-image-height image)))
          (width (if (> rate 0) (* rate old-width) (if (> old-width old-height) size (* size (/ old-width old-height)))))
          (height (if (> rate 0) (* rate old-height) (if (> old-width old-height) (* size (/ old-height old-width)) size)))
        )
        (gimp-image-scale image width height)
        (file-jpeg-save RUN-NONINTERACTIVE image drawable filename filename quality 0 1 1 "" 2 1 0 0)
        (gimp-image-delete image)
      )
      (set! filelist (cdr filelist))
    )
  )
)


Самый простой способ воспользоваться этой радостью — вставить (текстом, или из файла) в консоль Script-Fu, и нажать Enter. Теперь наша функция batch-resize доступна для использования. Пользуем так (в консоли): (batch-resize "C:\\images\\*.jpg" 640 1). Или так: (batch-resize "C:\\images\\i_am_clever_*.*" "25%" 0.75). Не забываем, что в строках нужно ескейпить слеши, поэтому в путях под Windows придётся слеши удваивать. Второй параметр — размер большей стороны, указанный числом (в пикселях) или строкой (если с процентом, то размер рассчитывается в процентах). Третий — качество сохраняемых JPEG картинок (от 0 до 1).





Дальше только для любознательных. :)

В функции file-jpeg-save кроме качества сохраняемой картинки задаются ещё некоторые параметры, влияющие на то же самое качество и, соответственно, размер. Описание параметров этой функции в просмотровщике процедур понятное, только нигде не написано какие индексы присвоены значениям субвыборки (4-й с конца параметр) и методу DCT (последний параметр). Я сохранял изображения с разными значениями этих параметров из самой программы и с помощью функции, и по размерам файлов вычислил нужные индексы.

Итак, для указания нужной субвыборки используются: 0 — 2×2–1×1–1×1 (по умолчанию, наихудшая передача цветов, наименьший файл), 1 — 2×1–1×1–1×1 (4:2:2, цвета передаются лучше), 2 — 1×1–1×1–1×1 (цвета не искажаются, файл больше других), 3 — 1×2–1×1–1×1 (по цветопередаче похож на 2×1–1×1–1×1, размер больше).

Методы DCT: 0 — целочисленный, 1 — быстрый целочисленный, 2 — с плавающей точкой. Визуально и по скорости работы я разницы не заметил, размеры файлов тоже совсем чуть-чуть отличались. Теоретически, с плавающей точкой выполняется медленнее и вносит меньше искажений.

В опубликованном выше сценарии используется целочисленный метод DCT (0) и тип субвыборки с наилучшей цветопередачей — 1×1–1×1–1×1 (2).

Ссылки по теме:
1. Хорошее, хоть и устаревшее описание Script-Fu на русском.
2. Описание языка Scheme. Здесь можно подсмотреть функции, которых нет в просморовщике процедур. Но следует учитывать, что в Script-Fu доступны далеко не все функции Scheme.
3. Описание Scheme и ещё ссылки на Википедии.
4. Справочное руководство по GIMP 2.0 Api.
5. Много разных сценариев, разбитых по категориям.
6. Ещё сценарии.
7. Наш сценарий с подсветкой синтаксиса и вложенности скобок.
Tags:
Hubs:
+39
Comments 72
Comments Comments 72

Articles