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

Conversione in batch di PNG in JPG in linux

Qualcuno conosce un buon modo per convertire in batch un gruppo di PNG in JPG in linux? (Io sto usando Ubuntu).

Un binario png2jpg che potrei semplicemente inserire in uno script di shell sarebbe l'ideale.

Risposte (10)

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

La vostra migliore scommessa sarebbe quella di usare Imagemagick

Non sono un esperto nell'uso effettivo, ma so che potete fare praticamente tutto ciò che riguarda l'immagine!

Un esempio è:

convert image.png image.jpg
``` ```
mogrify -format jpg *.png

e manterrà l'originale oltre a creare l'immagine convertita. Per quanto riguarda il batch. Penso che sia necessario utilizzare lo strumento Mogrify (dalla stessa linea di comando quando si è in imagemagick). Tenete presente che questo sovrascrive le vecchie immagini.

Il comando è:

&001

83
83
83
2013-01-28 02:45:11 +0000

Ho un paio di soluzioni in più.

La soluzione più semplice è come la maggior parte di quelle già pubblicate. Un semplice bash per il loop.

for i in *.png ; do convert "$i" "${i%.*}.jpg" ; done
``` ```
ls -1 *.png | xargs -n 1 bash -c 'convert "$0" "${0%.*}.jpg"'

Per qualche ragione tendo ad evitare i loop nel bash, quindi ecco un approccio più unixy xargs, usando il bash per il name-mangling.

ls -1 *.png | parallel convert '{}' '{.}.jpg'
``` ```
ls -1 *.png | parallel -j 3 convert '{}' '{.}.jpg'

Quello che uso. Utilizza GNU Parallel per eseguire più lavori contemporaneamente, dando un incremento delle prestazioni. È installato di default su molti sistemi ed è quasi sicuramente nel vostro repo (è un buon programma da avere in giro).

ls -1 *.png | parallel --eta convert '{}' '{.}.jpg'
``` ```
parallel convert '{}' '{.}.jpg' ::: *.png

Il numero di job predefinito al numero di processi che avete. Ho trovato un migliore utilizzo della CPU utilizzando 3 processi sul mio sistema dual-core.

parallel convert '{}' '{.}.jpg' -- *.png
``` &001 


E se volete alcune statistiche (un ETA, processi completati, tempo medio per processo...) 



&001 


C'è anche una sintassi alternativa se state utilizzando GNU Parallel. 


&001 &001 


E una sintassi simile per alcune altre versioni (incluso debian). 



&001
26
26
26
2009-11-16 03:28:26 +0000

Il comando convert che si trova su molte distribuzioni Linux è installato come parte della suite ImageMagick. Ecco il codice bash per eseguire convert su tutti i file PNG in una directory ed evitare il problema della doppia estensione:

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

Per chi vuole solo i comandi più semplici:

Convertire e tenere i file originali:

mogrify -format jpg *.png

Convertire e rimuovere i file originali:

mogrify -format jpg *.png && rm *.png
``` ```
bar.png
foo.png
foobar.jpg

Batch Converting Explained

Un po’ tardi per la festa, ma giusto per chiarire tutta la confusione per qualcuno che potrebbe non essere molto a suo agio con cli, ecco un riferimento e una spiegazione molto semplice.

Esempio di directory

mogrify -format jpg *.png
``` ```
bar.png
bar.jpg
foo.png
foo.jpg
foobar.jpg

Simple Convert

Mantiene tutti i file png originali e crea file jpg.

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

Risultato

bar.jpg
foo.jpg
foobar.jpg

Spiegazione

  • mogrify fa parte della suite di strumenti ImageMagick per l'elaborazione delle immagini.
  • mogrify elabora le immagini in place, cioè il file originale viene sovrascritto, ad eccezione dell'opzione -format. (Da il sito : This tool is similar to convert except that the original image file is overwritten (unless you change the file suffix with the -format option))
  • L'opzione - format specifica che si cambierà il formato, e il prossimo argomento deve essere il tipo (in questo caso, jpg).
  • Infine, *.png è il file di input (tutti i file che terminano in .png).

Converti e rimuovi

Converte tutti i file png in jpg, rimuove l'originale.

for i in *.png; do mogrify -format jpg "$i" && rm "$i"; echo "$i converted to ${i%.*}.jpg"; done

Risultato

find . -iname '*.png' | while read i; do mogrify -format jpg "$i" && rm "$i"; echo "Converted $i to ${i%.*}.jpg"; done
``` ```
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

Spiegazione

  • La prima parte è esattamente come sopra, creerà nuovi file jpg.
  • Il && è un operatore booleano. In breve:
  • Quando un programma termina, restituisce uno stato di uscita. Uno stato di 0 significa nessun errore.
  • Poiché && esegue valutazione di corto circuito , la parte giusta sarà eseguita solo se non ci sono stati errori. Questo è utile perché si potrebbe non voler cancellare tutti i file originali se ci fosse un errore di conversione.
  • Il comando rm cancella i file.

Fancy Stuff

Ora ecco alcune chicche per le persone che sono a proprio agio con il cli.

Se si desidera un po’ di output durante la conversione dei file:

&001 &001

Convertire tutti i file png in tutte le sottodirectory e dare output per ognuno:

&001 &001

Convertire tutti i file png in tutte le sottodirectory, mettere tutti i jpg risultanti nella directory all, numerarli, rimuovere i file png originali e visualizzare l'output per ogni file mentre avviene:

&001

8
8
8
2009-11-16 05:29:10 +0000

Il comando “png2jpg” che state cercando è in realtà diviso in due comandi chiamati pngtopnm e cjpeg, e fanno parte rispettivamente dei pacchetti netpbm e libjpeg-progs.

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

la mia soluzione rapidafor 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

Molti anni troppo tardi, c'è un'utilità png2jpeg specifica per questo scopo, che ho creato io.

Adattamento del codice da parte di @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

Per l'elaborazione in batch:

for img in *.png; do
  convert "$img" "$img.jpg"
done
``` &001 


Alla fine, però, si otterranno nomi di file come image1.png.jpg. 


Questo funzionerà in bash, e forse bourne. Non conosco altre conchiglie, ma l'unica differenza sarebbe probabilmente la sintassi del loop.
1
1
1
2016-09-17 02:34:45 +0000

Questo è ciò che uso per convertire quando i file si estendono su più di una directory. Il mio originale era TGA a PNG

find . -name "*.tga" -type f | sed 's/\.tga$//' | xargs -I% convert %.tga %.png

Il concetto è che tu find i file che ti servono, togli l'estensione e poi la aggiungi di nuovo con xargs. Quindi per PNG a JPG, cambiereste le estensioni e fareste una cosa in più per trattare con i canali alfa, cioè impostare lo sfondo (in questo esempio bianco, ma potete cambiarlo) e poi appiattire l'immagine

find . -name "*.png" -type f | sed 's/\.png$//' | xargs -I% convert %.png -background white -flatten %.jpg