2009-11-16 02:06:38 +0000 2009-11-16 02:06:38 +0000
172
172

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.

Respostas (10)

247
247
247
2009-11-16 02:15:29 +0000

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
83
83
83
2013-01-28 02:45:11 +0000

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
26
26
26
2009-11-16 03:28:26 +0000

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
11
11
11
2015-10-17 15:02:05 +0000

tl;dr

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

Batch Converting Explained

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

Simple Convert

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

  • mogrify faz parte do conjunto ImageMagick de ferramentas para processamento de imagens.
  • mogrify processa imagens no local, o que significa que o ficheiro original é sobreescrito, com excepção da opçã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))
  • A opção - format especifica que o formato será alterado, e o próximo argumento precisa ser o tipo (neste caso, jpg).
  • Finalmente, *.png são os ficheiros de entrada (todos os ficheiros terminados em .png).

Converte e Remove

Converte todos os ficheiros png para jpg, remove o original.

mogrify -format jpg *.png && rm *.png

Resultado

bar.jpg
foo.jpg
foobar.jpg

Explicação

  • A primeira parte é exactamente a mesma que a anterior, irá criar novos ficheiros jpg.
  • O && é um operador booleano. Em resumo:
  • Quando um programa termina, ele retorna um estado de saída. Um status de 0 significa sem erros.
  • Como && 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.
  • O comando rm apaga ficheiros.

Fancy Stuff

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
8
8
8
2009-11-16 05:29:10 +0000

O verdadeiro comando “png2jpg” que procura está na realidade dividido em dois comandos chamados pngtopnm e cjpeg, que fazem parte dos pacotes netpbm e libjpeg-progs, respectivamente.

png2pnm foo.png | cjpeg > foo.jpeg
6
6
6
2014-10-13 17:12:00 +0000
find . -name "*.png" -print0 | xargs -0 mogrify -format jpg -quality 50
5
5
5
2012-05-07 12:42:40 +0000

a minha solução rápidafor i in $(ls | grep .png); do convert $i $(echo $i.jpg | sed s/.png//g); done

4
4
4
2016-10-22 09:37:31 +0000

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
3
3
3
2009-11-16 02:28:02 +0000

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.

1
1
1
2016-09-17 02:34:45 +0000

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