Question Conversion par lots de PNG en JPG sous Linux


Est-ce que quelqu'un connaît un bon moyen de convertir par lots un groupe de fichiers PNG en fichiers JPG sous Linux? (J'utilise Ubuntu).

Un binaire png2jpg que je pourrais simplement insérer dans un script shell serait idéal.


141
2017-11-16 02:06


origine




Réponses:


Votre meilleur pari serait d'utiliser Imagemagick

Je ne suis pas un expert de l'utilisation réelle, mais je sais que vous pouvez pratiquement tout faire avec cette image!

Un exemple est:

convert image.png image.jpg

et il conservera l'original ainsi que la création de l'image convertie. Comme pour le lot. Je pense que vous devez utiliser l'outil Mogrify (à partir de la même ligne de commande dans imagemagick). Gardez à l'esprit que cela écrase les anciennes images.

La commande est la suivante:

mogrify -format jpg *.png  

210
2017-11-16 02:15



Génial, c'est exactement ce que je recherchais et je le réutiliserai. Soit dit en passant, juste pour clarifier, car je ne savais pas que c'était ce que vous vouliez dire: convertir est utilisé pour générer un fichier de sortie séparé, mogrify est utilisé pour modifier l'image d'origine. - nedned
images png avec fond transparent ne convertit pas correctement en jpg. - vishnu
Pour convertir les fichiers PNG avec un arrière-plan transparent, utilisez la commande suivante: mogrify -format jpg -background black -flatten *.png - hyperknot
@KevinCox sur ma boîte Linux après mogrify -format jpeg img.png J'ai 2 fichiers et file img.* rapporte un png, l'original intact et un nouveau fichier JPEG. Alors mogrify Est-ce que ne pas écraser les fichiers originaux dans ce cas. - neurino
De mogrify Documentation: "Cet outil est similaire à convert sauf que le fichier d’image original est écrasé (sauf si vous modifiez le suffixe du fichier avec le -format option) avec toutes les modifications que vous demandez." - janko-m


J'ai deux autres solutions.

La solution la plus simple est comme la plupart déjà affichée. Un simple bash pour la boucle.

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

Pour une raison quelconque, j'ai tendance à éviter les boucles dans bash, alors voici une approche xix plus unixy, en utilisant bash pour la gestion des noms.

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

Celui que j'utilise Il utilise GNU Parallel pour exécuter plusieurs tâches à la fois, ce qui vous permet d'améliorer vos performances. Il est installé par défaut sur de nombreux systèmes et est presque définitivement dans votre dépôt (c'est un bon programme à avoir autour).

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

Le nombre de travaux par défaut correspond au nombre de processus que vous avez. J'ai trouvé une meilleure utilisation du processeur en utilisant 3 travaux sur mon système dual-core.

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

Et si vous voulez des statistiques (un ETA, les travaux terminés, le temps moyen par emploi ...)

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

Il existe également une autre syntaxe si vous utilisez GNU Parallel.

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

Et une syntaxe similaire pour d'autres versions (y compris debian).

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

67
2018-01-28 02:45



+1 pour une extension correcte de la chaîne bash dans le si, si je pouvais vous donner un autre commentaire pour mentionner le parallèle, je le ferais. Il y a une faute de frappe, cependant - vous avez besoin d'un done à la fin de cela pour la boucle. De plus, pour les choses en parallèle, vous pouvez éviter de l'utiliser lset pipe avec une construction comme: parallel -j 3 --eta convert '{}' '{.}.jpg' ::: *.png (voir ici) - evilsoup
Correction d'une faute de frappe. C'est une syntaxe cool que je ne connaissais pas. Je ne sais pas lequel j'aime le mieux pour probablement la même raison que je préfère ne pas utiliser de boucles en bash. Je mets la solution parce que c'est probablement la manière la plus "correcte" mais je vais probablement rester avec le ls méthode pour moi-même parce que cela a plus de sens pour moi. - Kevin Cox
... bien qu'il faille noter que cette syntaxe ne fonctionne que sur GNU parallèle. Le parallèle mis en place dans certaines distributions Linux (comme Debian et Ubuntu) est en fait une version différente avec une syntaxe légèrement différente (utilisez -- plutôt que :::) - et même dans ce cas, il lui manque certaines des fonctionnalités de GNU Parallel. - evilsoup
(bien que ceux sur les distributions qui n’emballent pas GNU parallèlement puissent l’installer facilement du code source, en utilisant les instructions ici) - evilsoup
Je pense que je devrais le changer à l’époque pour qu’il fonctionne avec autant de versions que possible. - Kevin Cox


le convert La commande trouvée sur de nombreuses distributions Linux est installée dans le cadre de la suite ImageMagick. Voici le code bash à exécuter convert sur tous les fichiers PNG d'un répertoire et éviter ce problème de double extension:

for img in *.png; do
    filename=${img%.*}
    convert "$filename.png" "$filename.jpg"
done

25
2017-11-16 03:28



Selon la page de manuel de convert: "Le programme de conversion est membre de la suite d’outils ImageMagick (1)." - nedned
Vous avez raison. Pour une raison quelconque, je pensais que cela faisait partie d'une bibliothèque différente. De toute façon, le code que j'ai posté ci-dessus est la bonne façon d'automatiser la conversion par lots dans un répertoire. - Marcin
Vous pouvez utiliser l'expansion de bash pour améliorer cette commande comme suit: for f in *.png; do convert "$f" "${f/%png/jpg}"; done - evilsoup
rappelez-vous juste qu'il est sensible à la casse. mon appareil photo le nomme * .JPG et ne l'a pas réalisé en première instance. - tsenapathy


L'actuel "png2jpg"la commande que vous recherchez est en réalité divisée en deux commandes appelées pngtopnm et cjpeg, et ils font partie de la netpbm et libjpeg-progs paquets, respectivement.

png2pnm foo.png | cjpeg > foo.jpeg

7
2017-11-16 05:29





tl; dr

Pour ceux qui veulent juste les commandes les plus simples:

Convertir et garder fichiers originaux:

mogrify -format jpg *.png

Convertir et retirer fichiers originaux:

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

Conversion par lots expliquée

Un peu tard pour la fête, mais juste pour clarifier toute la confusion pour quelqu'un qui n'est peut-être pas très à l'aise avec Cli, voici une référence et une explication superbes.

Répertoire d'exemples

bar.png
foo.png
foobar.jpg

Simple Convertir

Conserve tous les fichiers png d'origine et crée des fichiers jpg.

mogrify -format jpg *.png

Résultat

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

Explication

  • mogrifier fait partie de la ImageMagick suite d'outils de traitement d'images.
    • mogrifier traite les images en place, ce qui signifie que le fichier d'origine est écrasé, à l'exception du fichier -format option. (De le 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))
  • le - format option spécifie que vous allez changer le format, et le prochain argument doit être le type (dans ce cas, jpg).
  • Enfin, *.png est les fichiers d'entrée (tous les fichiers se terminant par .png).

Convertir et supprimer

Convertit tous les fichiers png en jpg, supprime les originaux.

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

Résultat

bar.jpg
foo.jpg
foobar.jpg

Explication

  • La première partie est exactement la même que ci-dessus, elle créera de nouveaux fichiers jpg.
  • le && est un opérateur booléen. En bref:
    • Lorsqu'un programme se termine, il renvoie un statut de sortie. Un statut de 0 signifie pas d'erreurs.
    • Depuis && effectue évaluation de court-circuit, la bonne partie ne sera effectuée que si il n'y avait pas d'erreurs. Ceci est utile car vous ne souhaitez peut-être pas supprimer tous les fichiers d'origine en cas d'erreur lors de leur conversion.
  • le rm commande supprime les fichiers.

Trucs De Fantaisie

Maintenant, voici quelques cadeaux pour les gens qui sont à l'aise avec le cli.

Si vous souhaitez une sortie lors de la conversion de fichiers:

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

Convertir tous les fichiers png dans tous les sous-répertoires et donner des résultats pour chacun d'eux:

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

Convertir tous les fichiers png dans tous les sous-répertoires, mettre tous les jpgs obtenus dans le all répertoire, les numéroter, supprimer les fichiers png d'origine et afficher la sortie pour chaque fichier tel qu'il se produit:

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

6
2017-10-17 15:02



Probablement la meilleure réponse à condition de vous débarrasser de la while read part (remplacez-le ou retirez-le tous ensemble) ... - don_crissti
@don_crissti, qu'est-ce qui ne va pas en lecture? - Steven Jeffries
Il est sujet aux erreurs (à moins d'être sûr à 100% que vous avez affaire à des noms de fichiers sains) et lent (comme en très, très, très lent). - don_crissti
Quelle est la qualité JPG par défaut et comment conserver les horodatages des fichiers? - Dan Dascalescu
@DanDascalescu Les méthodes ci-dessus (à l'exception de la dernière) conserveront les noms de fichiers, mais remplaceront leur extension, donc les fichiers horodatés devraient être corrects (faites toujours une copie et testez-les d'abord). Selon ImageMagick, "la valeur par défaut consiste à utiliser la qualité estimée de votre image en entrée si elle peut être déterminée, sinon 92" (imagemagick.org/script/command-line-options.php#quality) La qualité peut être spécifiée avec -quality <nombre> où <nombre> est compris entre 1 et 100. - Steven Jeffries


find . -name "*.png" -print0 | xargs -0 mogrify -format jpg -quality 50

4
2017-10-13 17:12



Merci pour une solution en ligne de répertoire profonde / récursive qui laisse le résultat *.jpg fichiers à côté de l'original *.png fichiers, montre comment réduire la taille / qualité du fichier et ne se casse pas à cause de caractères étranges dans le répertoire ou le nom du fichier. - Joel Purra


ma solution rapide for i in $(ls | grep .png); do convert $i $(echo $i.jpg | sed s/.png//g); done


3
2018-05-07 12:42



Cela doit être l'une des lignes de commande les plus laides et les plus compliquées que j'ai jamais vues - evilsoup
@evilsoup honnêtement, c'est élégant pour les scripts shell. Le prétendre est compliqué n'est pas juste. - Max Howell
@MaxHowell homme. Non, ce serait une version élégante de ceci: for f in ./*.png; do convert "$f" "${f%.*}.jpg"; done. Cela évite le complètement inutile ls, grep et sed appels (et echo, mais l'IIRC qui est un bash builtin et n'aura donc pas / très peu d'impact sur les performances), et se débarrasse de deux pipes et de deux sous-couches, et implique moins de frappe. Il est même légèrement plus portable, car toutes les versions de ls sont sûrs à analyser. - evilsoup
@evilsoup je suis corrigé! Bon travail. - Max Howell


Pour le traitement par lots:

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

Vous allez vous retrouver avec des noms de fichiers comme image1.png.jpg.

Cela fonctionnera dans bash, et peut-être bourne. Je ne connais pas d'autres shells, mais la seule différence serait probablement la syntaxe de la boucle.


2
2017-11-16 02:28





Bien des années trop tard, il y a un png2jpeg utilitaire spécifiquement à cette fin, que je suis l'auteur.

Adapter le code par @Marcin:

#!/bin/sh

for img in *.png
do
    filename=${img%.*}
    png2jpeg -q 95 -o "$filename.jpg" "$filename.png"
done

2
2017-10-22 09:37





C'est ce que j'utilise pour convertir lorsque les fichiers couvrent plusieurs répertoires. Mon original était TGA to PNG

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

Le concept est vous find les fichiers dont vous avez besoin, enlevez l'extension puis rajoutez-la avec xargs. Donc, pour le format PNG vers JPG, vous devez modifier les extensions et faire une chose supplémentaire pour gérer les canaux alpha, à savoir définir l’arrière-plan (dans cet exemple, en blanc, mais vous pouvez le changer), puis aplatir l’image.

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

0
2017-09-17 02:34