Conversão em linux
Alguém conhece uma boa maneira de converter um monte de PNG em JPG em linux? (Estou a usar Ubuntu).
Um binário png2jpg que eu pudesse simplesmente inserir num script de shell seria o ideal.
Alguém conhece uma boa maneira de converter um monte de PNG em JPG em linux? (Estou a usar Ubuntu).
Um binário png2jpg que eu pudesse simplesmente inserir num script de shell seria o ideal.
A sua melhor aposta seria usar Imagemagick
Não sou especialista na utilização real, mas sei que pode fazer praticamente qualquer imagem relacionada com isto!
Um exemplo é:
convert image.png image.jpg
e manterá a imagem original, bem como a imagem convertida. Quanto ao lote. Penso que é necessário utilizar a ferramenta Mogrify (a partir da mesma linha de comando quando em imagemagick). Tenha em mente que este sobreescreve as imagens antigas.
O comando é:
mogrify -format jpg *.png
Tenho mais algumas soluções.
A solução mais simples é como a maioria já publicada. Uma simples bash para o loop.
for i in *.png ; do convert "$i" "${i%.*}.jpg" ; done
Por alguma razão tenho tendência a evitar loops em bash, por isso aqui está uma abordagem mais unixi xargs, usando bash para o name-mangling.
ls -1 *.png | xargs -n 1 bash -c 'convert "$0" "${0%.*}.jpg"'
A que eu uso. Utiliza o GNU Parallel para executar múltiplos trabalhos ao mesmo tempo, dando-lhe um aumento de desempenho. É instalado por defeito em muitos sistemas e está quase definitivamente no seu repo (é um bom programa para ter por perto).
ls -1 *.png | parallel convert '{}' '{.}.jpg'
O número de trabalhos por defeito é o número de processos que tem. Eu encontrei melhor uso de CPU usando 3 trabalhos no meu sistema dual-core.
ls -1 *.png | parallel -j 3 convert '{}' '{.}.jpg'
E se você quiser algumas estatísticas (uma ETA, trabalhos completados, tempo médio por trabalho…)
ls -1 *.png | parallel --eta convert '{}' '{.}.jpg'
Há também uma sintaxe alternativa se você estiver usando o GNU Parallel.
parallel convert '{}' '{.}.jpg' ::: *.png
E uma sintaxe similar para algumas outras versões (incluindo o debian).
parallel convert '{}' '{.}.jpg' -- *.png
O comando convert
encontrado em muitas distribuições Linux está instalado como parte da suite ImageMagick. Aqui está o código bash para executar o convert
em todos os ficheiros PNG num directório e evitar esse duplo problema de extensão:
for img in *.png; do
filename=${img%.*}
convert "$filename.png" "$filename.jpg"
done
Para aqueles que apenas querem os comandos mais simples:
Convert e keep* ficheiros originais:
mogrify -format jpg *.png
Convert e remove ficheiros originais:
mogrify -format jpg *.png && rm *.png
Kinda late to the party, but just to clear up all of the confusion for someone who may not be very comfortable with cli, here’s a super dumbed down reference and explanation.
Example Directory
bar.png
foo.png
foobar.jpg
Mantém todos os ficheiros png originais, assim como cria ficheiros jpg.
mogrify -format jpg *.png
Resultado
bar.png
bar.jpg
foo.png
foo.jpg
foobar.jpg
Explicação
-format
. (A partir de do site : This tool is similar to convert except that the original image file is overwritten (unless you change the file suffix with the -format option)
) - format
especifica que o formato será alterado, e o próximo argumento precisa ser o tipo (neste caso, jpg). *.png
são os ficheiros de entrada (todos os ficheiros terminados em .png). mogrify -format jpg *.png && rm *.png
Resultado
bar.jpg
foo.jpg
foobar.jpg
Explicação
&&
é um operador booleano. Em resumo: 0
significa sem erros. &&
executa avaliação de curto-circuito , a parte direita só será executada se não houver erros. Isto é útil porque pode não querer apagar todos os ficheiros originais se houver um erro a convertê-los. rm
apaga ficheiros. Agora aqui ficam algumas guloseimas para as pessoas que estão confortáveis com o cliente.
Se quiser alguma saída enquanto está a converter ficheiros:
for i in *.png; do mogrify -format jpg "$i" && rm "$i"; echo "$i converted to ${i%.*}.jpg"; done
Converta todos os ficheiros png em todas as subdirectorias e dê saída para cada um:
find . -iname '*.png' | while read i; do mogrify -format jpg "$i" && rm "$i"; echo "Converted $i to ${i%.*}.jpg"; done
Converta todos os ficheiros png em todas as subdirectorias, coloque todos os jpgs resultantes no directório all
, numere-os, remova os ficheiros png originais e mostre a saída para cada ficheiro à medida que este se processa:
n=0; find . -iname '*.png' | while read i; do mogrify -format jpg "$i" && rm "$i"; fn="all/$((n++)).jpg"; mv "${i%.*}.jpg" "$fn"; echo "Moved $i to $fn"; done
Muitos anos demasiado tarde, existe uma utilidade png2jpeg específica para este fim, de minha autoria.
Adaptando o código por @Marcin:
#!/bin/sh
for img in *.png
do
filename=${img%.*}
png2jpeg -q 95 -o "$filename.jpg" "$filename.png"
done
Para processamento em lote:
for img in *.png; do
convert "$img" "$img.jpg"
done
Você vai acabar com nomes de arquivos como image1.png.jpg.
Isto vai funcionar em bash, e talvez bourne. Eu não sei sobre outras shells, mas a única diferença provavelmente seria a sintaxe do laço.
Isto é o que eu uso para converter quando os ficheiros abrangem mais do que um directório. O meu original era TGA para PNG
find . -name "*.tga" -type f | sed 's/\.tga$//' | xargs -I% convert %.tga %.png
O conceito é você find
os ficheiros que precisa, tire a extensão e volte a adicioná-la com xargs
. Assim, para PNG para JPG, você alteraria as extensões e faria uma coisa extra para lidar com os canais alfa, nomeadamente definir o fundo (neste exemplo branco, mas você pode alterá-lo) e depois aplanar a imagem
find . -name "*.png" -type f | sed 's/\.png$//' | xargs -I% convert %.png -background white -flatten %.jpg