Ustaw przezroczyste tło za pomocą ImageMagick i wiersza poleceń

120

Załóżmy, że masz dowolny obraz (PNG lub JPG). Ten obraz ma białe tło i muszę ustawić przezroczyste tło.

Próbowałem z tymi przykładami:

  • convert original.png -background none transparent.png
  • convert original.png -background white -flatten -alpha off transparent.png

ale bez pożądanych rezultatów.

Jak mam to zrobić?

WAŻNE: Korzystanie z convertwiersza poleceń.

Izrael
źródło
Dziwne - myślałem, że odpowiednie polecenie jest, convert original.png -transparent white new.pngale 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)?
mathematical.coffee
@ mathematical.coffee Ok, rozumiem, sprawdzę czy tak nie jest i będę kontynuował ten wątek. Dziękuję Ci.
Izrael
@ mathematical.coffee Witam ponownie, sprawdziłem kolory i ten obrazek ma tło typu #FFFFFF, innymi słowy "białe". :( Tak nie jest!
Izrael

Odpowiedzi:

140

Używam ImageMagick 6.6.9-7 na Ubuntu 12.04.
U mnie zadziałało:

convert test.png -transparent white transparent.png

To zmieniło całą biel w test.png na przezroczystą.

Rijk
źródło
6
To nie zadziałało, dopóki nie zdałem sobie sprawy, że JPG nie będzie przezroczysty. Kiedy przełączyłem się na PNG, zrobił dokładnie to, co chciałem - po prostu zmieniłem „biały” na „rgb ($ r, $ g, $ b)”.
Roger Dueck
2
Do cholery! to jest świetne!
agilob
2
Spowoduje to nie tylko konwersję tła na przezroczyste, ale także każdy biały piksel. Czy istnieje sposób na przekonwertowanie samego tła na przezroczyste?
Alejandro Lozdziejski
2
@AlejandroLozdziejski - jak definiujesz "tło"?
Jules
1
@AlejandroLozdziejski: Dobre pytanie. Zobacz moje rozwiązanie, które wykorzystuje wypełnienie od krawędzi, szukając kolorów w przybliżeniu takich samych jak w lewym górnym pikselu.
hackerb9
79

Miałem ten sam problem. W którym muszę usunąć białe tło z formatu obrazu jpg / png za pomocą ImageMagick.

U mnie zadziałało:

1) Konwertuj format obrazu na png: convert input.jpg input.png

2) convert input.png -fuzz 2% -transparent white output.png

Sandeep Pal
źródło
6
To dobrze, aby uzyskać gładszą krawędź między przezroczystym tłem a nieprzezroczystym pierwszym planem. Jeśli konwertujesz zaszumione ikony w JPG na PNG i chcesz dodać przezroczystość, możesz również dodać filtrowanie mediany:mogrify -format png -median 2 -fuzz 5% -transparent white ico_*.jpg
Tomasz Gandor
44

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).

Prosta zamiana bieli na przezroczystą nie zawsze działa Antyaliasowany kanał alfa i wypełnienie zalewowe wyglądają znacznie lepiej

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.

Skrypt bg_removal: ma brodę, ale brakuje mu wygładzania krawędzi

hackerb9
źródło
2
Musiałem zmodyfikować fuzz na 2%, ponieważ obraz zawiera białą maszynę z białym tłem. I chociaż nie jest to w 100% idealne, jest to najlepsze rozwiązanie, jakie znalazłem, ponieważ nie chcę robić tego ręcznie gimpani w ogóle . :)
tukusejssirs
1
Świetne rozwiązanie!
0x01h
29

To działa dla mnie:

convert original.png -fuzz 10% -transparent white transparent.png

gdzie im mniejszy% fuzz, tym bliżej do prawdziwej bieli lub odwrotnie, im większy procent, tym większe odchylenie od bieli może stać się przezroczyste

Ricibald
źródło
1
Łał! Właśnie tego potrzebowałem! before: i.imgur.com/2Rd7w1N.png , after: i.imgur.com/4RTYygo.png
Dorian
Nie działa idealnie, ponieważ nie obsługuje obrazów z białym kolorem i białym tłem. jak zdjęcia atutowe.
Starszy kierownik zespołu programistów PHP
Aby uzyskać biały na białym, spróbuj użyć rozwiązania do napełniania zalewowego, które opublikowałem powyżej . Lub użyj mojego mktransskryptu powłoki: github.com/hackerb9/mktrans
hackerb9
12

Możesz użyć tego, aby uczynić tło przezroczystym

convert test.png -background rgba(0,0,0,0) test1.png

Powyższe daje prefektowi przezroczyste tło

Sanat Kumar Panda
źródło
4
Powłoka może wymagać cytowania (): convert more-icon.png -gravity center -background 'rgba(0,0,0,0)' -extent 27x27 new-more-icon.png
Jim K.
7

Używając ImageMagick, jest to bardzo podobne do kodu i wyniku hackerb9, ale jest trochę prostszą linią poleceń. Zakłada się, że lewy górny piksel to kolor tła. Po prostu wypełniam tło przezroczystością, następnie wybieram kanał alfa i rozmywam go oraz usuwam połowę rozmytego obszaru za pomocą -level 50x100%. Następnie ponownie włącz wszystkie kanały i spłaszcz go w stosunku do brązowego koloru. -Blur 0x1 -poziom 50x100% działa antyialiasowo na granice przezroczystości kanału alfa. Możesz dostosować wartość rozmycia, wielkość rozmycia i wartość -level 50%, aby zmienić stopień wygładzania krawędzi.

convert logo: -fuzz 25% -fill none -draw "matte 0,0 floodfill" -channel alpha -blur 0x1 -level 50x100% +channel -background saddlebrown -flatten result.jpg

wprowadź opis obrazu tutaj

fmw42
źródło
Miły. Podoba mi się, że zrozumiałeś to w zwięzłej linii. Jest to podobne do jednego z moich pośrednich kroków podczas pisania scenariusza. Zdecydowałem się na to, ponieważ (a) traci zbyt wiele ostrych szczegółów, (b) chciałem, aby wybór koloru był oczywisty, aby można go było łatwo zmienić, oraz (c) chciałem wypełnić wszystkie krawędzie, a nie tylko górę -lewy róg. (Mogą być inne rzeczy, o których teraz zapominam).
hackerb9
2
PS Zgaduję, że „fmw” oznacza Freda M. Weinhausa. Jeśli tak, to pozdrowienia, dr Weinhaus! Każdemu, kto nie wie, kim jest, napisał kilka przełomowych badań nad grafiką komputerową, które rozpoczęły się w latach siedemdziesiątych XX wieku. Każdy powinien sprawdzić jego niesamowitą konukopię skryptów powłoki ImageMagick na stronie fmwconcepts.com/imagemagick .
hackerb9
1
@ hackerb9: Tak, to ja. Czy my się znamy? Wyślij mi e-mail, jeśli chcesz. Mój adres e-mail znajduje się na mojej stronie internetowej, do której jesteś podłączony.
fmw42
4

Jeśli chcesz kontrolować poziom przezroczystości, możesz użyć rgba. gdzie a jest alfa. 0 dla przezroczystych i 1 dla nieprzezroczystych. Upewnij się, że końcowy plik wyjściowy musi mieć rozszerzenie .png, aby był przezroczysty.

convert 
  test.png 
    -channel rgba 
    -matte 
    -fuzz 40% 
    -fill "rgba(255,255,255,0.5)" 
    -opaque "rgb(255,255,255)" 
       semi_transparent.png
Gokul NK
źródło
1

Tak. Miałem ten sam problem. Oto polecenie, które uruchomiłem i zadziałało idealnie: convert transparent-img1.png transparent-img2.png transparent-img3.png -channel Alpha favicon.ico

stacigh
źródło