Respostas:
Sua melhor aposta seria usar o Imagemagick
Não sou especialista no uso real, mas sei que você pode fazer praticamente qualquer imagem relacionada a isso!
Um exemplo é:
convert image.png image.jpg
e manterá o original, além de criar a imagem convertida. Quanto ao lote. Eu acho que você precisa usar a ferramenta Mogrify (na mesma linha de comando, quando estiver no imagemagick). Lembre-se de que isso substitui as imagens antigas.
O comando é:
mogrify -format jpg *.png
mogrify -format jpg -background black -flatten *.png
mogrify -format jpeg img.png
eu ter 2 arquivos e file img.*
relatar um png, o original intocado e um novo jpeg. Portanto mogrify
, não substitui os arquivos originais nesse caso.
mogrify
documentação: " Esta ferramenta é semelhante a, convert
exceto que o arquivo de imagem original é substituído (a menos que você altere o sufixo do arquivo com a opção -format ) com as alterações solicitadas. "
Eu tenho mais algumas soluções.
A solução mais simples é como a maioria já publicada. Uma festança simples para loop.
for i in *.png ; do convert "$i" "${i%.*}.jpg" ; done
Por alguma razão, eu tendem a evitar loops no bash, então aqui está uma abordagem xargs mais unix, usando o bash para a identificação de nomes.
ls -1 *.png | xargs -n 1 bash -c 'convert "$0" "${0%.*}.jpg"'
O que eu uso. Ele usa o GNU Parallel para executar vários trabalhos ao mesmo tempo, oferecendo um aumento de desempenho. Ele é instalado por padrão em muitos sistemas e está quase definitivamente no seu repositório (é um bom programa para se ter por perto).
ls -1 *.png | parallel convert '{}' '{.}.jpg'
O número de trabalhos é padronizado com o número de processos que você possui. Encontrei melhor uso da CPU usando 3 tarefas no meu sistema dual-core.
ls -1 *.png | parallel -j 3 convert '{}' '{.}.jpg'
E se você quiser algumas estatísticas (um ETA, trabalhos concluídos, 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 semelhante para algumas outras versões (incluindo debian).
parallel convert '{}' '{.}.jpg' -- *.png
done
no final do loop for. Além disso, para o material paralela, você poderia evitar o uso que ls
e tubo com uma construção como: parallel -j 3 --eta convert '{}' '{.}.jpg' ::: *.png
(ver aqui )
ls
método por mim mesmo, porque faz mais sentido para mim.
--
ao invés de :::
) - e mesmo assim, carece frustrantemente de alguns dos recursos do paralelo GNU.
O convert
comando encontrado em muitas distribuições Linux é instalado como parte do pacote ImageMagick. Aqui está o código bash para executar convert
em todos os arquivos PNG em um diretório e evitar esse problema de extensão dupla:
for img in *.png; do
filename=${img%.*}
convert "$filename.png" "$filename.jpg"
done
for f in *.png; do convert "$f" "${f/%png/jpg}"; done
Para quem quer apenas os comandos mais simples:
Converta e mantenha arquivos originais:
mogrify -format jpg *.png
Converta e remova arquivos originais:
mogrify -format jpg *.png && rm *.png
Meio atrasado para a festa, mas apenas para esclarecer toda a confusão de alguém que pode não estar muito confortável com o CLI, aqui está uma referência e explicação super estúpidas.
Diretório de exemplo
bar.png
foo.png
foobar.jpg
Mantém todos os arquivos png originais, bem como cria arquivos jpg.
mogrify -format jpg *.png
Resultado
bar.png
bar.jpg
foo.png
foo.jpg
foobar.jpg
Explicação
-format
opção. (A partir 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
opção especifica que você alterará o formato e o próximo argumento precisa ser do tipo (neste caso, jpg).*.png
estão os arquivos de entrada (todos os arquivos que terminam em .png).Converte todos os arquivos png em jpg, remove o original.
mogrify -format jpg *.png && rm *.png
Resultado
bar.jpg
foo.jpg
foobar.jpg
Explicação
&&
é um operador booleano. Em resumo:
0
significa sem erros.&&
realiza a avaliação de curto-circuito , a parte correta somente será executada se não houver erros . Isso é útil porque você pode não querer excluir todos os arquivos originais se houver um erro ao convertê-los.rm
comando exclui arquivos.Agora, aqui estão alguns presentes para as pessoas que se sentem confortáveis com o CLI.
Se você quiser alguma saída enquanto estiver convertendo arquivos:
for i in *.png; do mogrify -format jpg "$i" && rm "$i"; echo "$i converted to ${i%.*}.jpg"; done
Converta todos os arquivos png em todos os subdiretórios 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 arquivos png em todos os subdiretórios, coloque todos os jpgs resultantes no all
diretório, numere- os, remova os arquivos png originais e exiba a saída de cada arquivo conforme ele ocorre:
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
while read
parte (substituí-lo ou removê-lo todos juntos) ...
find . -name "*.png" -print0 | xargs -0 mogrify -format jpg -quality 50
*.jpg
arquivos resultantes próximos aos *.png
arquivos originais , mostra como reduzir o tamanho / qualidade e não quebra por causa de caracteres estranhos no diretório ou no nome do arquivo.
minha solução rápida
for i in $(ls | grep .png); do convert $i $(echo $i.jpg | sed s/.png//g); done
for f in ./*.png; do convert "$f" "${f%.*}.jpg"; done
. Isso evita o completamente desnecessário ls
, grep
e sed
chama (e echo
, mas o IIRC que é um bash embutido e, portanto, terá pouco / muito pouco impacto no desempenho) e se livra de dois pipes e dois subshells, e envolve menos digitação. É ainda um pouco mais portátil, pois nem todas as versões ls
são seguras para analisar.
Muitos anos tarde demais, existe um utilitário png2jpeg especificamente para esse fim, que eu criei.
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ê terminará com nomes de arquivo como image1.png.jpg.
Isso funcionará no bash e talvez no bourne. Não conheço outras conchas, mas a única diferença provavelmente seria a sintaxe do loop.
É isso que eu uso para converter quando os arquivos abrangem mais de um diretório. Meu original era TGA para PNG
find . -name "*.tga" -type f | sed 's/\.tga$//' | xargs -I% convert %.tga %.png
O conceito é que find
você precisa dos arquivos, retire a extensão e adicione-a novamente xargs
. Portanto, para PNG e JPG, você alteraria as extensões e faria uma coisa extra para lidar com canais alfa: definir o plano de fundo (neste exemplo, branco, mas você pode alterá-lo) e achatar a imagem.
find . -name "*.png" -type f | sed 's/\.png$//' | xargs -I% convert %.png -background white -flatten %.jpg