А вот с этим проблема, поскольку украденный мной набор png-файлов сделан только в чёрном исполнении. Сам я в дизайне полный ноль, всякими Gimp-ами владею очень слабо и вообще, как создаются подобные изображения понятия не имею: я пробовал создать такое просто кодом с помощью градиентов, закруглений и т.п., но так хорошо никак не получается.
И я решил просто по-пиксельно заменить все цвета оригинальных изображений на новые, которые будут вычисляться на основе базового цвета. В оригинальных файлах основным цветом является rgb(30, 30, 30), но для создания эффекта тени используется переход данного цвета в чёрный. Функция translate-color вычисляет новый цвет на основе базового и опирается на rgb(30, 30, 30) как на основу старого изображения:
(defun translate-color (orig base-color)
(iter (for i in orig)
(for j in base-color)
(collect (min (max (+ i j -30) 0)
255))))
Для создания png-файлов есть известное и хорошее решение - ZPNG, а вот библиотеки для разбора png-файлов я не знал и кажется такая библиотека не освещалось широко где-либо, по крайней мере, я не видел. Однако, быстрый поиск в гугл сразу показал мне библиотеку png-read. Я опробовал её на нескольких примерах и кажется она "просто работает". Таким образом, я смог записать такой код по изменению цвета нужных мне изображений: (iter (for i in orig)
(for j in base-color)
(collect (min (max (+ i j -30) 0)
255))))
(defun make-other-png (orig dest base-color)
(let* ((orig-png (png-read:read-png-file orig))
(orig-image (png-read:image-data orig-png))
(png (make-instance 'zpng:png
:color-type :truecolor-alpha
:width (png-read:width orig-png)
:height (png-read:height orig-png)))
(image (zpng:data-array png)))
(iter (for w from 0 below (png-read:width orig-png))
(iter (for h from 0 below (png-read:height orig-png))
(iter (for c in (translate-color (list (aref orig-image w h 0)
(aref orig-image w h 1)
(aref orig-image w h 2))
base-color))
(for i from 0)
(setf (aref image h w i) c))
(setf (aref image h w 3)
(aref orig-image w h 3))))
(zpng:write-png png dest)))
Функция make-other-png принимает путь к оригинальному файлу, путь для сохранения нового изображения и цвет, который должен являться базовым для нового изображения.(let* ((orig-png (png-read:read-png-file orig))
(orig-image (png-read:image-data orig-png))
(png (make-instance 'zpng:png
:color-type :truecolor-alpha
:width (png-read:width orig-png)
:height (png-read:height orig-png)))
(image (zpng:data-array png)))
(iter (for w from 0 below (png-read:width orig-png))
(iter (for h from 0 below (png-read:height orig-png))
(iter (for c in (translate-color (list (aref orig-image w h 0)
(aref orig-image w h 1)
(aref orig-image w h 2))
base-color))
(for i from 0)
(setf (aref image h w i) c))
(setf (aref image h w 3)
(aref orig-image w h 3))))
(zpng:write-png png dest)))
Опробовал данный код и остался очень доволен результатом. Вот что получается в результате вызова
(make-other-png "win_LB.png" "out.png" '(0 192 0))
Слева оригинальное изображение, а с права получившееся в результате преобразования.
P.S. Ebuild для png-read я добавил в свой форк gentoo-lisp-overlay.
Вот он, подход настоящего программиста!
ОтветитьУдалитьНам, простым смертным, остаётся по-прежнему пользоваться -colorize в ImageMagick. Или Colours/Colourise... в Gimp.