Решение
color=$( convert filename.png -format "%[pixel:p{0,0}]" info:- )
convert filename.png -alpha off -bordercolor $color -border 1 \
\( +clone -fuzz 30% -fill none -floodfill +0+0 $color \
-alpha extract -geometry 200% -blur 0x0.5 \
-morphology erode square:1 -geometry 50% \) \
-compose CopyOpacity -composite -shave 1 outputfilename.png
объяснение
Это немного длиннее, чем приведенные ранее простые ответы, но дает гораздо лучшие результаты: (1) качество выше из-за сглаживания альфа- канала , и (2) удаляется только фон, а не один цвет. («Фон» определяется как примерно того же цвета, что и верхний левый пиксель, с использованием заливки по краям изображения.)
Кроме того, альфа-канал также размывается на полпикселя, чтобы избежать ореолов. Конечно, морфологические операции ImageMagick (пока?) Не работают на субпиксельном уровне, поэтому вы можете видеть, что я увеличиваю альфа-канал до 200% перед размывом.
Сравнение результатов
Вот сравнение простого подхода («-fuzz 2% -transparent white») с моим решением при запуске на
логотипе ImageMagick . Я выровнял оба прозрачных изображения на коричневом фоне, чтобы различия были очевидны (нажмите, чтобы увидеть оригиналы).
Обратите внимание, как при простом подходе исчезла борода Волшебника. Сравните края мастера, чтобы увидеть, как сглаженная альфа помогает фигуре плавно переходить в фон.
Конечно, я полностью признаю, что бывают случаи, когда вы можете захотеть использовать более простое решение. (Например: его намного легче запомнить, и если вы конвертируете в GIF, вы все равно ограничены 1-битным альфа-каналом.)
сценарий оболочки mktrans
Поскольку вы вряд ли захотите вводить эту команду несколько раз, я рекомендую обернуть ее в сценарий. Вы можете загрузить сценарий оболочки BASH с github, который выполняет предложенное мной решение. Его можно запускать для нескольких файлов в каталоге и включать полезные комментарии на случай, если вы захотите что-то изменить.
bg_removal скрипт
Кстати, ImageMagick на самом деле поставляется со скриптом под названием
«bg_removal»,
который использует floodfill так же, как и мое решение. Однако результаты невысокие, потому что он по-прежнему использует 1-битный альфа-канал. Кроме того, сценарий bg_removal работает медленнее и немного сложнее в использовании (он требует, чтобы вы указали два разных значения нечеткости). Вот пример вывода bg_removal.
convert original.png -transparent white new.png
но, попробовав ее, не могу заставить ее работать. Кстати, вы уверены, что ваш фон на самом деле белый (#FFFFFF) или он просто почти белый (например, #FEFEFE)?