ImageMagick конвертируется в png8 (PNG с палитрой в двоичном формате альфа), используя цвет фона для частично прозрачных пикселей - PullRequest
1 голос
/ 20 июня 2019

У меня есть 32-битное PNG-изображение, подобное этому:

32-bit

Отображается здесь с фоном шахматной доски для наглядности, но вместо шахматной доски изображение фактически прозрачное (дляВаша ссылка: оригинальное 32-битное изображение ).Как вы можете видеть, по краям и вправо красные пиксели постепенно исчезают с непрозрачного на прозрачный.

Если бы я отображал это 32-битное изображение поверх синего фона, пиксели вокругкрая и вправо постепенно исчезнут с красного на синий.

Теперь мне нужно преобразовать это изображение в 8-битный PNG с двоичной альфа-версией.Я хочу, чтобы полностью прозрачная область оставалась полностью прозрачной , но частично прозрачные пиксели постепенно смешивались с намеченным фоновым / матовым цветом , в данном примере синим.

Так что-то вроде этого:

8-bit blended with background color

Однако я не могу понять, как это сделать с помощью ImageMagick (используя ImageMagick 7.0.8-26 на Mac).Я попытался сделать следующее:

magick original.png -background 'rgba(0,0,255,0)' png8:output.png

Но это приводит к:

8-bit with background color ignored

Кажется, что синий цвет фона вообще игнорируется,и просто преобразуйте прозрачность в двоичную (возможно, с полной непрозрачностью для ≥128 или полностью прозрачной для <128). </p>

Также, если я укажу rgb(0,0,255) в качестве цвета фона (то есть без альфа), результат будет таким же.

Есть ли в ImageMagick какой-нибудь умный вариант «смешивание фона для частично прозрачных пикселей», о котором я не знаю?

В противном случае, я предполагаю, что мне следует каким-то образом извлечь двоичное растровое изображение, в котором исходное изображение полностью прозрачно (т.е. имеет альфа-значение или непрозрачность 0), затем сгладить изображение на выбранном мной фоне, а затем повторно-применить булево альфа-изображение снова.Но не совсем уверен, как это сделать.

Ответы [ 4 ]

2 голосов
/ 20 июня 2019

Один из способов сделать это с помощью ImageMagick - извлечь альфа-канал, раскрасить практически все, кроме полностью прозрачных пикселей, и объединить исходное изображение с результатом.

convert input.png \( +clone -alpha extract -transparent black -fill blue \
   -channel RGB -colorize 100 +channel \) +insert -composite output.png

, который считывает входное изображение,клонирует его в скобках и извлекает альфа-канал в черно-белую маску.

Чистый черный становится прозрачным с "-прозрачным черным".

Белый, все, кроме чистого черного, изменяется на синий с "-colorize 100".Параметр «-channel RGB» применяет этот цвет заливки только к белой части маски и игнорирует прозрачный.

Затем, после скобок, «+ insert» перемещает это изображение на прозрачном синем фоне назад,и «-composite» помещает входное изображение поверх синего и прозрачного.

Если вы используете ImageMagick версии 7, используйте «magick» вместо «convert».Если вы работаете в Windows, измените обратную косую черту в конце строки "\" на каретку "^" и удалите обратную косую черту, которая выходит за скобки "\ (... \)" на просто "(...)".

2 голосов
/ 20 июня 2019

Я могу придумать два метода, но я уверен, что у людей есть лучшие ответы.

Первый вариант

Скомпонуйте синий фон, а затем скопируйте альфа-канал из исходного источника.

magick original.png \( \
  +clone \( +clone -fill BLUE -draw 'color 0,0 reset' \) \
  -compose DstOver -composite \) \
  -swap 0,1 -compose CopyAlpha -composite  PNG8:output.png

output

Второй вариант

Заменить прозрачный синим цветом, но затем вызвать -transparent без какой-либо операции -fuzz.

magick original.png \( \
  +clone -fill BLUE -draw 'color 0,0 reset' \) \
  -compose DstOver -composite -transparent BLUE \
  PNG8:output.png

output

Опять же, я уверен, что приведенные выше примеры могут быть улучшены. YMMV

1 голос
/ 21 июня 2019

Вот еще один способ в ImageMagick.

enter image description here

convert img.png \
\( -clone 0 -alpha extract -channel rgba \
    \( xc:none xc:blue +append \) -clut +channel \
        -channel alpha -threshold 0 +channel \) \
+swap -compose over -composite PNG8:result.png


ИЛИ ДЛЯ Imagemgick 7

magick img.png \
\( -clone 0 -alpha extract -alpha copy -channel rgba \
\( xc:none xc:blue +append \) -clut \
-channel alpha -threshold 0 +channel \) \
+swap -compose over -composite PNG8:result.png

enter image description here

Read the image.

Clone it, extract the alpha channel, create transparent blue color map and apply to the alpha channel, then threshold the alpha channel.

Swap the two images and composite the original over the processed alpha channel.

Save the output.
0 голосов
/ 20 июня 2019

Благодаря опубликованным предложениям, проблема в том, что я не хочу маскировать какой-либо конкретный цвет (например, черный или синий) прозрачным. Тот же самый цвет может также появиться в непрозрачных частях.

После некоторых настроек я получил именно тот результат, который мне нужен:

magick original.png -write MPR:foo -background 'rgb(0,0,255)' -flatten \( MPR:foo -alpha extract -threshold 0 \) -compose copy_opacity -composite png8:result.png

Пояснение:

  • Я начинаю с original.png и использую -write MPR:foo, чтобы сохранить временную копию в памяти под названием 'foo'
  • Затем я сглаживаю изображение на синем фоне, давая правильные значения цвета везде (включая смешивание с фоном для частично прозрачных пикселей), но теряя данные непрозрачности.
  • Затем я обрабатываю второй слой, открывая то же самое исходное входное изображение (восстанавливая из памяти, используя MPR:foo), и извлекаю его альфа-канал, который теперь становится серым изображением, содержащим исходные альфа-данные.
  • Я применяю -threshold 0 к этому слою, который изменяет все значения канала, которые были> 0 до максимума (то есть альфа 255 или полностью непрозрачные), и ≤0 остается 0 (полностью прозрачным). Так что теперь это мой бинарный альфа-канал.
  • Затем, наконец, я объединяю эти два слоя, используя композит copy_opacity, который просто копирует 2-й слой (двоичная альфа) и записывает его в качестве альфа-данных результирующего слоя.
  • Сохранение конечного результата дает мне точное изображение, которое мне нужно.
...