Для чего: недавно открыл для себя тему Reflektions, из которой решил сделать аналог гномьего ACYL (Any Color You Like). Сделал скрипт, который с помощью imagemagick (у самого стоит graphicsmagick) перекашивает абсолютно черные и белые области, оставляя цветные и серые нетронутыми.
Сейчас используется такая последовательность:
1. Создаются маски путем копирования "серого канала" - для черной и белой областей.
2. На их основе создаются цветные слои, которые затем накладываются на исходное изображение.
Проблема в том, что цветные и серые области частично закрашиваются, т.к. соответствующие области слоев полупрозрачны.
Перед этим я пробовал использовать -mask, который согласно `man gm` должен пропускать только чисто черные области (то что надо), но вне зависимости от того, как это достигается (он вообще брал все не-белые области, решил путем правки самой маски), в результате обе маски оставляют нетронутыми промежуточные пикселы на границах цветных областей, что совсем нехорошо при инвертировании исходных цветов (например, black->LightBlue & white->black).
Использование -sharpen на этапе создания масок частично решило проблему, но некоторые отдельные пикселы все равно "бъются" (по аналогии с мониторами ).
Из за этого и решил попробовать вариант со слоями, но те же грабли все-равно мешаются.
Пример иконки media-zip:
Оригинальная
С использованием слоев, black->DarkBlue white->LightGreen
Предыдущий алгоритм с использованием -mask, -sharpen и дополнительного обрезания серых пикселов маски
доп. иконки Akregator, KMag - эту раскраску я сейчас использую (что происходит без -sharpen - лучше 100 раз услышать или прочитать %) ).
p.s. Еще раз присмотрелся к Akregator, похоже там проблемные пикселы вообще прозрачные.
imagemagick: Выделение по цвету со сглаживанием
Модератор: Модераторы разделов
-
- Сообщения: 178
- ОС: Gentoo / Calculate
-
- Сообщения: 178
- ОС: Gentoo / Calculate
Re: imagemagick: Выделение по цвету со сглаживанием
Собственно скрипты:
Предыдущий вариант:
Последний вариант:
Предыдущий вариант:
Код: Выделить всё
#!/bin/bash
img_src="$1"
img_dest="$2"
color_dark="$3"
color_light="$4"
tmpdir="/tmp/colorize_reflektion_$UID"
if ! test -d "$tmpdir" ; then
test -e "$tmpdir" && rm -rf "$tmpdir"
mkdir "$tmpdir"
fi
# Implementation 1: simple color replacement
#convert $img -fill "#302015" -opaque white -fill "#ffe0a0" -opaque black ./icon-out-opaque.png
#composite -compose In ./icon-out-opaque.png $img_src $img_dest
# Implementation 2: more complex, using masks
img_size=$( identify -format '%w,%h' "$img_src" )
# Mask creation
convert "$img_src" -channel gray -sharpen 3 $tmpdir/icon-mask-b.png
convert "$img_src" -channel gray -sharpen 3 -negate $tmpdir/icon-mask-w.png
# Mask fix - imagemagick treats gray mask parts as black
cp $tmpdir/icon-mask-b.png $tmpdir/icon-mask-b-tmp.png
convert $tmpdir/icon-mask-b.png \
-fill white -mask $tmpdir/icon-mask-w.png -draw "rectangle 0,0 $img_size" \
$tmpdir/icon-mask-b.png
convert $tmpdir/icon-mask-w.png \
-fill white -mask $tmpdir/icon-mask-b-tmp.png -draw "rectangle 0,0 $img_size" \
$tmpdir/icon-mask-w.png
convert $img_src \
-fill "$color_dark" -mask $tmpdir/icon-mask-b.png -draw "rectangle 0,0 $img_size" \
-fill "$color_light" -mask $tmpdir/icon-mask-w.png -draw "rectangle 0,0 $img_size" \
$tmpdir/icon-out-opaque.png
composite -compose In $tmpdir/icon-out-opaque.png $img_src $img_dest
Последний вариант:
Код: Выделить всё
# Implementation 2: more complex, using masks
img_size=$( identify -format '%w,%h' "$img_src" )
# Mask creation
convert "$img_src" -channel gray -negate $tmpdir/icon-mask-b.png
convert "$img_src" -channel gray $tmpdir/icon-mask-w.png
# Coloration layers
convert $tmpdir/icon-mask-b.png \
-fill "$color_dark" -draw "rectangle 0,0 $img_size" \
$tmpdir/black-part.png
composite -compose CopyOpacity $tmpdir/icon-mask-b.png $tmpdir/black-part.png $tmpdir/black-part.png
convert $tmpdir/icon-mask-w.png \
-fill "$color_light" -draw "rectangle 0,0 $img_size" \
$tmpdir/white-part.png
composite -compose CopyOpacity $tmpdir/icon-mask-w.png $tmpdir/white-part.png $tmpdir/white-part.png
# Extract original color parts
convert "$img_src" \
-preview Saturation \
$tmpdir/color-part.png
convert "$img_src" \
-draw "image Over 0,0 $img_size $tmpdir/white-part.png" \
-draw "image Over 0,0 $img_size $tmpdir/black-part.png" \
$tmpdir/icon-out-opaque.png
composite -compose In $tmpdir/icon-out-opaque.png $img_src $img_dest