Batch-Konvertierung von PNG in JPG in Linux

187452
nedned

Kennt jemand eine gute Möglichkeit, eine Reihe von PNGs in Linux in JPGs umzuwandeln? (Ich benutze Ubuntu).

Eine png2jpg-Binärdatei, die ich einfach in ein Shell-Skript schreiben könnte, wäre ideal.

143

10 Antworten auf die Frage

214
William Hilsum

Am besten verwenden Sie Imagemagick

Ich bin kein Experte für die tatsächliche Verwendung, aber ich weiß, dass Sie alles, was mit diesem Bild zusammenhängt, machen können!

Ein Beispiel ist:

convert image.png image.jpg 

Das Original bleibt erhalten und das konvertierte Bild wird erstellt. Wie für die Charge. Ich denke, Sie müssen das Mogrify-Werkzeug verwenden (von der gleichen Befehlszeile aus, wenn Sie sich im Imagemagick befinden). Beachten Sie, dass dies überschreibt die alten Bilder werden.

Der Befehl lautet:

mogrify -format jpg *.png 
Toll, das war genau das, wonach ich gesucht habe und wieder benutzen werde. Übrigens, nur zur Klarstellung, da ich nicht wusste, dass Sie dies gemeint haben: Mit convert wird eine separate Ausgabedatei erstellt, mit mogrify wird das Originalbild geändert. nedned vor 14 Jahren 7
PNG-Bilder mit transparentem Hintergrund werden nicht ordnungsgemäß in JPG konvertiert. vishnu vor 12 Jahren 1
Verwenden Sie den folgenden Befehl, um PNGs mit transparentem Hintergrund zu konvertieren: `mogrify -format jpg -background black -flatten * .png` hyperknot vor 11 Jahren 3
Ich frage mich, wie man die Originaldateien überschreiben kann *, wenn sich * der Dateiname ändert ... Jpg-Dateien bleiben unangetastet;) Ah, +1 neurino vor 10 Jahren 0
@neurino The file name isn't changed in the mogrify example. The files still have a `.png` extension but are jpeg images. Try using `file img.png` (after running mogrify) and it will tell you that it is a jpeg image. Kevin Cox vor 10 Jahren 0
@KevinCox auf meiner Linux-Box nach 'mogrify -format jpeg img.png' Ich habe 2 Dateien und `file img. *` Meldet ein png, das Original unberührt und ein neues jpeg. 'Mogrify' überschreibt in diesem Fall also keine Originaldateien. neurino vor 10 Jahren 3
@neurino Interesting. From the mogrify man page: "mogrify - resize an image, blur, crop, despeckle, dither, draw on, flip, join, re-sample, and much more. Mogrify overwrites the original image file, whereas, convert(1) writes to a different image file." So I don't know why that happens on your box. Kevin Cox vor 10 Jahren 0
@neurino This happens on my box as well. Now I'm really confused, it this a bug? Or an undocumented feature? Kevin Cox vor 10 Jahren 0
Aus der mogrify-Dokumentation: "* Dieses Tool ähnelt" convert ", mit der Ausnahme, dass die ursprüngliche Bilddatei überschrieben wird (es sei denn, Sie ändern das Dateisuffix mit der Option ** - format **) mit den von Ihnen angeforderten Änderungen. *" janko-m vor 9 Jahren 4
Wenn Sie Ihre PNG-Dateien stärker komprimieren müssen, verwenden Sie `mogrify -quality 75 -format jpg * .png` Flatron vor 7 Jahren 0
Ich auch heute auf Ubuntu Desktop 16 - Originaldateien bleiben erhalten Nam G VU vor 7 Jahren 0
70
Kevin Cox

Ich habe noch ein paar Lösungen.

Die einfachste Lösung ist wie die meisten bereits veröffentlicht. Eine einfache Bash-for-Loop.

for i in *.png ; do convert "$i" "$.jpg" ; done 

Aus irgendeinem Grund neige ich dazu, Schleifen in bash zu vermeiden, daher gibt es hier einen unixy xargs-Ansatz, bei dem bash für das Namensmangling verwendet wird.

ls -1 *.png | xargs -n 1 bash -c 'convert "$0" "$.jpg"' 

Die, die ich benutze. Es verwendet GNU Parallel, um mehrere Jobs gleichzeitig auszuführen, wodurch Sie die Leistung steigern können. Es wird standardmäßig auf vielen Systemen installiert und ist fast definitiv in Ihrem Repo enthalten (es ist ein gutes Programm, um es zu haben).

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

Die Anzahl der Jobs entspricht standardmäßig der Anzahl der Prozesse, die Sie haben. Ich habe eine bessere CPU-Auslastung mit 3 Jobs auf meinem Dual-Core-System gefunden.

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

Und wenn Sie Statistiken wünschen (ETA, abgeschlossene Jobs, durchschnittliche Zeit pro Job ...)

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

Es gibt auch eine alternative Syntax, wenn Sie GNU Parallel verwenden.

parallel convert '{}' '{.}.jpg' ::: *.png 

Und eine ähnliche Syntax für einige andere Versionen (einschließlich Debian).

parallel convert '{}' '{.}.jpg' -- *.png 
+1 für die korrekte Bash-String-Erweiterung in der for, wenn ich Ihnen eine weitere positive Erwähnung geben könnte, würde ich das parallel erwähnen. Es gibt jedoch einen Tippfehler - Sie benötigen am Ende dieser for-Schleife ein "erledigt". Für das parallele Zeug könnten Sie die Verwendung von `ls 'und Pipe mit einem Konstrukt wie folgt vermeiden:` parallel -j 3 --eta convert' {} '' {.}. Jpg '::: * .png` ( [hier] (http://www.gnu.org/software/parallel/man.html#example__reading_arguments_from_command_line)) evilsoup vor 11 Jahren 2
Fixed typo. That is a cool syntax that I didn't know of. I don't know which one I like better for probably the same reason I prefer not to use loops in bash. I put it the solution because it is probably the more "proper" way but I'll probably stick with the `ls` method for myself because it makes more sense to me. Kevin Cox vor 11 Jahren 0
...although it should be noted that that syntax only works on GNU parallel. The parallel that's packaged in some linux distros (like Debian & Ubuntu) is actually a different version with a slightly different syntax (use `--` rather than `:::`) - and even then, it frustratingly lacks some of the features of GNU parallel. evilsoup vor 11 Jahren 1
(Auch wenn diese auf Distros, die GNU nicht parallel verpacken, diese einfach von der Quelle installieren können, verwenden Sie die Anweisungen [hier] (http://askubuntu.com/a/142757/112879)) evilsoup vor 11 Jahren 0
Ich denke, ich sollte es damals ändern, damit es mit so vielen Versionen wie möglich funktioniert. Kevin Cox vor 11 Jahren 0
Wenn Sie ein Verzeichnis mit mehr als 10.000 PNG-Bildern haben, schlägt der Befehl ls wahrscheinlich fehl. Dieser Befehl funktioniert also in solchen Situationen: `find. -type f -name '* .png' | parallel --eta convert '{}' '{.}. jpg "" Ahi Tuna vor 5 Jahren 0
25
Marcin

Der convertBefehl vieler Linux-Distributionen wird als Teil der ImageMagick-Suite installiert. Hier ist der Bash-Code, der convertfür alle PNG-Dateien in einem Verzeichnis ausgeführt werden kann, um das Problem der doppelten Erweiterung zu vermeiden:

for img in *.png; do filename=$ convert "$filename.png" "$filename.jpg" done 
Laut der Manpage für convert: "Das convert-Programm ist Mitglied der ImageMagick (1) -Suite von Tools." nedned vor 14 Jahren 8
Du hast Recht. Aus irgendeinem Grund dachte ich, es wäre Teil einer anderen Bibliothek. In jedem Fall ist der von mir veröffentlichte Code der richtige Weg, die Stapelkonvertierung innerhalb eines Verzeichnisses zu automatisieren. Marcin vor 14 Jahren 1
You can use bash expansion to improve that command like: `for f in *.png; do convert "$f" "$"; done` evilsoup vor 11 Jahren 2
Denken Sie nur daran, dass es die Groß- und Kleinschreibung berücksichtigt Meine Kamera nennt es "* .JPG" und hat dies zunächst nicht erkannt. tsenapathy vor 8 Jahren 0
7
Teddy

Die eigentliche „ png2jpg“ Befehl Sie suchen, ist in Wirklichkeit spaltete sich in zwei Befehle genannt pngtopnmund cjpeg, und sie sind ein Teil der netpbmund libjpeg-progsPakete sind.

png2pnm foo.png | cjpeg > foo.jpeg 
7
Steven Jeffries

tl; dr

Für diejenigen, die nur die einfachsten Befehle wünschen:

Konvertieren und behalten Sie Originaldateien:

mogrify -format jpg *.png 

Konvertieren und entfernen Sie Originaldateien:

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

Stapelverarbeitung erklärt

Ein bisschen spät zur Party, aber nur um all die Verwirrung für jemanden aufzuklären, der sich mit cli vielleicht nicht sehr wohl fühlt, hier ist eine verdammte Referenz und Erklärung.

Beispielverzeichnis

bar.png foo.png foobar.jpg 

Einfach konvertieren

Behält alle ursprünglichen PNG-Dateien bei und erstellt JPG-Dateien.

mogrify -format jpg *.png 

Ergebnis

bar.png bar.jpg foo.png foo.jpg foobar.jpg 

Erläuterung

  • mogrify ist Teil der ImageMagick- Suite von Tools zur Bildverarbeitung.
    • mogrify verarbeitet Bilder anstelle der Originaldatei Bedeutung überschrieben wird, mit Ausnahme der -formatOption. (Von der Website : This tool is similar to convert except that the original image file is overwritten (unless you change the file suffix with the -format option))
  • Die - formatOption gibt an, dass Sie das Format ändern, und das nächste Argument muss der Typ sein (in diesem Fall jpg).
  • Zuletzt *.pngsind die Eingabedateien (alle Dateien, die auf .png enden).

Konvertieren und entfernen

Konvertiert alle PNG-Dateien in JPG, entfernt das Original.

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

Ergebnis

bar.jpg foo.jpg foobar.jpg 

Erläuterung

  • Der erste Teil ist derselbe wie oben, er erzeugt neue JPG-Dateien.
  • Das &&ist ein boolescher Operator. Zusamenfassend:
    • Wenn ein Programm beendet wird, wird ein Beendigungsstatus zurückgegeben. Ein Status von 0bedeutet keine Fehler.
    • Da &&eine Kurzschlussauswertung durchgeführt wird, wird der rechte Teil nur ausgeführt, wenn keine Fehler aufgetreten sind . Dies ist nützlich, da Sie möglicherweise nicht alle Originaldateien löschen möchten, wenn beim Konvertieren ein Fehler aufgetreten ist.
  • Der rmBefehl löscht Dateien.

Schickes Zeug

Hier sind einige Goodies für die Leute, die mit dem Cli vertraut sind.

Wenn Sie während der Konvertierung von Dateien etwas Ausgabe wünschen:

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

Konvertieren Sie alle PNG-Dateien in allen Unterverzeichnissen und geben Sie für jedes eine Ausgabe aus:

find . -iname '*.png' | while read i; do mogrify -format jpg "$i" && rm "$i"; echo "Converted $i to $.jpg"; done 

Konvertieren Sie alle PNG-Dateien in allen Unterverzeichnissen, legen Sie alle resultierenden JPGs in das allVerzeichnis ab, nummerieren Sie sie, entfernen Sie die ursprünglichen PNN-Dateien und zeigen Sie die Ausgabe für jede Datei an, während sie stattfindet:

n=0; find . -iname '*.png' | while read i; do mogrify -format jpg "$i" && rm "$i"; fn="all/$((n++)).jpg"; mv "$.jpg" "$fn"; echo "Moved $i to $fn"; done 
Wahrscheinlich die beste Antwort, vorausgesetzt, Sie werden den Teil "beim Lesen" loswerden (ersetzen oder alle zusammen entfernen) ... don_crissti vor 8 Jahren 0
@ don_crissti, was ist los beim lesen? Steven Jeffries vor 8 Jahren 0
Es ist fehleranfällig (es sei denn, Sie sind zu 100% sicher, dass Sie mit vernünftigen Dateinamen zu tun haben) und langsam (wie sehr, sehr, sehr langsam). don_crissti vor 8 Jahren 0
Wie lautet die JPG-Standardqualität und wie können Dateizeitstempel beibehalten werden? Dan Dascalescu vor 6 Jahren 0
@DanDascalescu Die oben genannten Methoden (außer der letzten) behalten die Dateinamen bei, ersetzen jedoch die Erweiterung. Zeitstempel-Dateien sollten also in Ordnung sein (erstellen Sie immer eine Kopie und testen Sie zuerst). Laut ImageMagick "wird standardmäßig die geschätzte Qualität des Eingabebilds verwendet, wenn dies bestimmt werden kann, andernfalls 92" (http://www.imagemagick.org/script/command-line-options.php#quality) Qualität kann mit -quality angegeben werden woher ist 1 bis 100. Steven Jeffries vor 6 Jahren 0
Vielen Dank. `mogrify -format jpg foo.png` hat foo.jpg mit dem aktuellen Zeitstempel erstellt. Ich wollte den Zeitstempel von foo.png in foo.jpg kopieren, und ich sehe nichts dergleichen in den [Optionen] (https://www.imagemagick.org/script/mogrify.php). Dan Dascalescu vor 6 Jahren 0
4
emdog4
find . -name "*.png" -print0 | xargs -0 mogrify -format jpg -quality 50 
Vielen Dank für eine einzeilige Lösung mit tiefem / rekursivem Verzeichnis, bei der die resultierenden `* .jpg'-Dateien neben den ursprünglichen` * .png`-Dateien liegen, zeigt, wie die Dateigröße / -qualität reduziert werden kann, und bricht nicht aufgrund von ungeraden Zeichen ab im Verzeichnis oder Dateinamen. Joel Purra vor 9 Jahren 1
3
max

meine schnelle Lösung for i in $(ls | grep .png); do convert $i $(echo $i.jpg | sed s/.png//g); done

Dies muss eine der hässlichsten und verworrensten Befehlszeilen sein, die ich je gesehen habe evilsoup vor 11 Jahren 2
@evilsoup ehrlich gesagt, das ist elegant für Shell-Skripte. Die Behauptung, es sei verworren, ist nicht fair. Max Howell vor 10 Jahren 1
@ MaxHowell Mann. Hier wäre eine elegante Version davon: `for f in ./*.png; konvertiere "$ f" "$ . jpg"; fertig ". Dies vermeidet die völlig unnötigen "ls" -, "grep" - und "sed" -Aufrufe (und "echo", aber IIRC ist ein bash-Builtin und hat daher keine / nur eine geringe Auswirkung auf die Leistung) und beseitigt zwei Pipes und zwei Subshells , * und * beinhaltet weniger Tippen. Es ist sogar etwas tragbarer, da nicht alle Versionen von 'ls' sicher analysiert werden können. evilsoup vor 10 Jahren 8
@evilsoup Ich stehe korrigiert! Gut gemacht. Max Howell vor 10 Jahren 0
2
Jeffrey Aylesworth

Für die Stapelverarbeitung:

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

Sie erhalten jedoch Dateinamen wie image1.png.jpg.

Dies funktioniert in Bash und vielleicht auch in Bourne. Ich kenne keine anderen Shells, aber der einzige Unterschied wäre wahrscheinlich die Loop-Syntax.

2
user7023624

Viele Jahre zu spät, gibt es ein spezielles png2jpeg- Dienstprogramm, das ich erstellt habe.

Anpassung des Codes durch @Marcin:

#!/bin/sh  for img in *.png do filename=$ png2jpeg -q 95 -o "$filename.jpg" "$filename.png" done 
0
Archimedes Trajano

Dies ist, was ich zum Konvertieren verwende, wenn die Dateien mehr als ein Verzeichnis umfassen. Mein ursprünglicher war TGA to PNG

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

Das Konzept besteht aus findden Dateien, die Sie benötigen, entfernen Sie die Erweiterung und fügen Sie sie mit ein xargs. Bei PNG in JPG müssen Sie also die Erweiterungen ändern und noch etwas mit Alphakanälen tun, indem Sie den Hintergrund festlegen (in diesem Beispiel weiß, aber Sie können ihn ändern) und dann das Bild glätten

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