Defina o fundo transparente usando ImageMagick e prompt de linha de comando

119

Suponha que você tenha qualquer imagem (PNG ou JPG). Esta imagem tem um fundo branco e preciso torná-lo transparente.

Eu tentei com estes exemplos:

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

mas sem resultados desejáveis.

Como posso fazer isso?

IMPORTANTE: Usando a convertlinha de comando.

Israel
fonte
Estranho - pensei que o comando relevante era, convert original.png -transparent white new.pngmas ao tentar, não consigo fazê-lo funcionar. Como um aparte, você tem certeza de que o fundo é realmente branco (#FFFFFF) ou é apenas quase branco (por exemplo, #FEFEFE)?
mathematical.coffee
@ mathematical.coffee Ok, entendo, deixe-me verificar se este não é o caso e continuarei este tópico. Obrigado.
Israel
@ mathematical.coffee Olá novamente, eu verifiquei as cores e esta imagem tem fundo como #FFFFFF, em outras palavras, "branco". :( Este não é o caso!
Israel

Respostas:

140

Estou usando o ImageMagick 6.6.9-7 no Ubuntu 12.04.
O que funcionou para mim foi o seguinte:

convert test.png -transparent white transparent.png

Isso mudou todo o branco no test.png para transparente.

Rijk
fonte
6
Isso não funcionou para mim até que percebi que JPG não seria transparente. Assim que mudei para PNG, ele fez exatamente o que eu queria - apenas tive que mudar "branco" para "rgb ($ r, $ g, $ b)".
Roger Dueck
2
Merda! isso é ótimo!
agilob
2
Isso não apenas converterá o fundo em transparente, mas todos os pixels brancos. Existe uma maneira de converter o plano de fundo apenas em transparente?
Alejandro Lozdziejski
2
@AlejandroLozdziejski - como você está definindo "background"?
Jules
1
@AlejandroLozdziejski: Boa pergunta. Por favor, veja minha solução que usa um floodfill das bordas, procurando cores aproximadamente iguais ao pixel superior esquerdo.
hackerb9
79

Eu tive o mesmo problema. No qual eu tenho que remover o fundo branco do formato de imagem jpg / png usando ImageMagick.

O que funcionou para mim foi:

1) Converta o formato da imagem para png: convert input.jpg input.png

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

Sandeep Pal
fonte
6
Isso é bom, para ter uma borda mais lisa entre o fundo transparente e o primeiro plano opaco. Se você converter ícones barulhentos em JPG para PNG e quiser adicionar transparência, também poderá adicionar algum filtro de mediana:mogrify -format png -median 2 -fuzz 5% -transparent white ico_*.jpg
Tomasz Gandor
44

Solução

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

Explicação

Isso é um pouco mais longo do que as respostas simples fornecidas anteriormente, mas dá resultados muito melhores: (1) A qualidade é superior devido ao alfa suavizado e (2) apenas o fundo é removido, em oposição a uma única cor. ("Plano de fundo" é definido como aproximadamente da mesma cor do pixel superior esquerdo, usando um preenchimento das bordas da imagem.)

Além disso, o canal alfa também é corroído em meio pixel para evitar halos. Claro, as operações morfológicas do ImageMagick (ainda?) Não funcionam no nível de subpixel, então você pode ver que estou aumentando o canal alfa para 200% antes de erodir.

Comparação de resultados

Aqui está uma comparação da abordagem simples ("-fuzz 2% -transparent white") com a minha solução, quando executada no logotipo do ImageMagick . Eu aplainei as duas imagens transparentes em um fundo marrom escuro para tornar as diferenças aparentes (clique para ver os originais).

A simples substituição de branco por transparente nem sempre funciona Alphachannel e floodfill sem alisamento parecem muito melhores

Observe como a barba do Mago desapareceu na abordagem simples. Compare as bordas do Assistente para ver como o alfa suavizado ajuda a figura a se mesclar suavemente com o fundo.

Claro, eu admito completamente que às vezes você pode querer usar a solução mais simples. (Por exemplo: é muito mais fácil de lembrar e, se você estiver convertendo para GIF, estará limitado a alfa de 1 bit de qualquer forma.)

script shell mktrans

Como é improvável que você queira digitar esse comando repetidamente, recomendo envolvê-lo em um script. Você pode baixar um script de shell BASH do github que executa minha solução sugerida. Ele pode ser executado em vários arquivos em um diretório e inclui comentários úteis caso você queira ajustar as coisas.

script bg_removal

A propósito, o ImageMagick na verdade vem com um script chamado "bg_removal" que usa o floodfill de maneira semelhante à minha solução. No entanto, os resultados não são bons porque ele ainda usa alfa de 1 bit. Além disso, o script bg_removal executa mais devagar e é um pouco mais complicado de usar (requer que você especifique dois valores difusos diferentes). Aqui está um exemplo da saída de bg_removal.

O script bg_removal: tem barba, mas não tem suavização

hackerb9
fonte
2
Eu precisei modificar o fuzz para 2%, porque a imagem contém uma máquina branca com fundo branco. E embora isso não seja 100% perfeito, é a melhor solução que encontrei, pois não quero fazer isso manualmente gimpou algo assim. :)
tukusejssirs de
1
Solução incrível !
0x01h
29

Isso funciona para mim:

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

onde quanto menor a% de penugem, mais próximo do branco verdadeiro ou, inversamente, quanto maior a%, mais variação do branco pode se tornar transparente

Ricibald
fonte
1
Uau! Isso é exatamente o que eu precisava! antes: i.imgur.com/2Rd7w1N.png , depois: i.imgur.com/4RTYygo.png
Dorian
Não está funcionando perfeitamente porque não consegue lidar com imagens com cor branca e fundo branco. como fotos de trunfo.
Líder da equipe de programador PHP sênior
Para branco sobre branco, tente usar a solução de preenchimento que postei acima . Ou use meu mktransscript de shell: github.com/hackerb9/mktrans
hackerb9
12

Você pode usar isto para tornar o fundo transparente

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

O acima mostra o fundo transparente do prefeito

Sanat Kumar Panda
fonte
4
O shell pode exigir algumas citações de (): convert more-icon.png -gravity center -background 'rgba(0,0,0,0)' -extent 27x27 new-more-icon.png
Jim K.
7

Usando o ImageMagick, isso é muito semelhante ao código e ao resultado do hackerb9, mas é uma linha de comando um pouco mais simples. Ele assume que o pixel superior esquerdo é a cor de fundo. Eu apenas pingo o fundo com transparência, então seleciono o canal alfa, desfoco-o e removo metade da área desfocada usando -level 50x100%. Em seguida, ligue novamente todos os canais e alise-os contra a cor marrom. O -blur 0x1 -level 50x100% atua para suavizar os limites da transparência do canal alfa. Você pode ajustar o valor de fuzz, a quantidade de desfoque e o valor -level 50% para alterar o grau de suavização.

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

insira a descrição da imagem aqui

fmw42
fonte
Agradável. Eu gosto que você tenha a essência em uma linha sucinta. Isso é semelhante a uma das minhas etapas intermediárias enquanto escrevia o script. Decidi não fazer isso porque (a) perde muitos detalhes nítidos, (b) eu queria tornar a seleção de cores óbvia para que pudesse ser facilmente alterada e (c) eu queria preencher de todas as bordas, não apenas da parte superior -canto esquerdo. (Pode haver outras coisas que estou esquecendo agora).
hackerb9
2
PS: Vou supor que "fmw" significa Fred M. Weinhaus. Se sim, saudações, Dr. Weinhaus! Para quem não sabe quem ele é, ele escreveu algumas das pesquisas seminais em computação gráfica a partir dos anos 1970. Todos deveriam conferir sua incrível conucopia de scripts de shell do ImageMagick em fmwconcepts.com/imagemagick .
hackerb9
1
@ hackerb9: Sim, sou eu. Nós nos conhecemos? Envie-me um e-mail se desejar. Meu endereço de e-mail está na minha página da web que você vinculou.
fmw42 de
4

Se você deseja controlar o nível de transparência, pode usar rgba. onde a é o alfa. 0 para transparente e 1 para opaco. Certifique-se de que o arquivo de saída final deve ter extensão .png para transparência.

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
fonte
1

Sim. Tive esse mesmo problema também. Este é o comando que executei e funcionou perfeitamente: convert transparent-img1.png transparent-img2.png transparent-img3.png -channel Alpha favicon.ico

Stacigh
fonte