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.pngeu 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.
mogrifydocumentação: " Esta ferramenta é semelhante a, convertexceto 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
doneno final do loop for. Além disso, para o material paralela, você poderia evitar o uso que lse tubo com uma construção como: parallel -j 3 --eta convert '{}' '{.}.jpg' ::: *.png(ver aqui )
lsmé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 convertcomando encontrado em muitas distribuições Linux é instalado como parte do pacote ImageMagick. Aqui está o código bash para executar convertem 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
-formatopçã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))- formatopção especifica que você alterará o formato e o próximo argumento precisa ser do tipo (neste caso, jpg).*.pngestã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:
0significa 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.rmcomando 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 alldiretó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 readparte (substituí-lo ou removê-lo todos juntos) ...
find . -name "*.png" -print0 | xargs -0 mogrify -format jpg -quality 50
*.jpgarquivos resultantes próximos aos *.pngarquivos 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, grepe sedchama (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 lssã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 findvocê 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