Rozwiązanie
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
Wyjaśnienie
Jest to trochę dłużej niż podane wcześniej proste odpowiedzi, ale daje znacznie lepsze wyniki: (1) Jakość jest lepsza dzięki wygładzeniu alfa i (2) tylko tło jest usuwane w przeciwieństwie do pojedynczego koloru. („Tło” jest definiowane jako w przybliżeniu taki sam kolor jak górny lewy piksel, przy użyciu wypełnienia z krawędzi obrazu).
Dodatkowo kanał alfa ulega erozji o pół piksela, aby uniknąć aureoli. Oczywiście operacje morfologiczne ImageMagicka nie działają (jeszcze?) Na poziomie subpikseli, więc widać, że przed erozją zwiększam kanał alfa do 200%.
Porównanie wyników
Oto porównanie prostego podejścia („-fuzz 2% -przezroczysty biały”) z moim rozwiązaniem, gdy jest uruchamiane z
logo ImageMagick . Spłaszczyłem oba przezroczyste obrazy na siodłowo brązowym tle, aby różnice były widoczne (kliknij, aby zobaczyć oryginały).
Zwróć uwagę, jak broda czarodzieja zniknęła w prostym podejściu. Porównaj krawędzie kreatora, aby zobaczyć, w jaki sposób wygładzona alfa pomaga figurze płynnie wtapiać się w tło.
Oczywiście przyznaję, że są chwile, kiedy możesz chcieć skorzystać z prostszego rozwiązania. (Na przykład: jest o wiele łatwiejszy do zapamiętania, a jeśli konwertujesz na GIF, i tak jesteś ograniczony do 1-bitowej alfa).
Skrypt powłoki mktrans
Ponieważ jest mało prawdopodobne, abyś chciał wielokrotnie wpisywać to polecenie, zalecam zawinięcie go w skrypt. Możesz pobrać skrypt powłoki BASH z github, który wykonuje moje sugerowane rozwiązanie. Można go uruchomić na wielu plikach w katalogu i zawiera przydatne komentarze na wypadek, gdybyś chciał coś poprawić.
bg_removal script
Nawiasem mówiąc, ImageMagick zawiera skrypt o nazwie
„bg_removal”,
który używa funkcji floodfill w podobny sposób, jak moje rozwiązanie. Jednak wyniki nie są świetne, ponieważ nadal używa 1-bitowej alfa. Ponadto skrypt bg_removal działa wolniej i jest nieco trudniejszy w użyciu (wymaga określenia dwóch różnych wartości fuzz). Oto przykład danych wyjściowych z bg_removal.
convert original.png -transparent white new.png
ale po wypróbowaniu nie mogę go uruchomić. Na marginesie, czy jesteś pewien, że twoje tło jest rzeczywiście białe (#FFFFFF), czy jest po prostu prawie białe (np. #FEFEFE)?