Возникла на днях задача пакетно обработать 179 JPEG-файлов.
Была мысль сначала взять ImageMagick, но подумал, что мало приятного в его использовании. PIL (Python Imaging Library) использовать тоже не хотелось, потому что многие параметры там надо подкручивать вручную.
И тут вспомнил, что в Гимпе есть свой встроенный Лисп. Воображение сразу разгулялось =)
Открыл встроенную консоль для Script-Fu и нашёл пару статеек на Хабре (например, эта: https://habrahabr.ru/post/111387/ )
Но не тут-то было! Изначально хотелось писать скрипты в своём любимом Vim'e и удобно их отлаживать, но Гимп предлагает только примитивный REPL (который требует запись программы в одну строку) и каталог модулей, запуск которых идёт как будто в "чёрном ящике".
Обнаружил, что можно запустить сервер Script-Fu и подключаться к Гимпу удалённо. Протокол у него предельно простой, но вот нормальных готовых клиентов реализовано практически не было.
Один из них полностью на Perl (и перлом заправляет, т.е. никаких скобочек), другой на неизвестном диалекте Scheme, третий на Питоне (из исходников самого Гимпа) и ничего мне нужного не умеет.
Решил реализовать собственный, на Си, через сокеты. Для скачивания идти сюда: https://github.com/vit1-irk/gimp-exec
Всё, что он делает - это скармливает Scheme-овский исходник запущенному GIMP-серверу, который уже выполняет всю работу. Может быть, кому-нибудь пригодится.
* Запускаете GIMP-сервер (удобнее через меню "Фильтры" => "Script-Fu" => "Запустить сервер")
* Пишете скрипт в вашем любимом редакторе
* Скармливаете его командой gimp-exec your-script.scheme
* Всё
Дополнительные моменты в README.md репозитория.
А для конвертации получилось вот такое вот заклинание:
(gimp-message-set-handler 1) (let* ((files (cadr (file-glob "/путь/к/картинкам/*" 1)))) (while (not (null? files)) (let ( (filename (car files)) (new-filename "") (image 0) (layer 0) ) (set! image (car (gimp-file-load RUN-NONINTERACTIVE filename filename))) (set! layer (car (gimp-image-get-active-layer image))) (set! new-filename (string-append filename "-new.png")) (gimp-message (string-append "Обрабатываем " filename)) (gimp-levels-stretch layer) (gimp-brightness-contrast layer 0 40) (gimp-posterize layer 10) (gimp-image-convert-grayscale image) (gimp-image-convert-indexed image 2 3 10 FALSE TRUE "colors") (file-png-save RUN-NONINTERACTIVE image layer new-filename new-filename 0 9 0 0 0 1 0) (gimp-image-delete image) ) (set! files (cdr files)) ) )
За отступы и оформление кода в целом не ругайте, по-другому читать ЭТО не получается =)