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

Conversión por lotes de PNG a JPG en linux

¿Alguien sabe una buena manera de convertir por lotes un montón de PNG en JPG en linux? (Estoy usando Ubuntu).

Un binario png2jpg que pudiera soltar en un shell script sería ideal.

Respuestas (10)

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

Tu mejor apuesta sería usar Imagemagick

No soy un experto en el uso real, pero sé que puedes hacer casi cualquier imagen relacionada con esto!

Un ejemplo es:

convert image.png image.jpg

y mantendrá el original así como la creación de la imagen convertida. En cuanto al lote. Creo que necesitas usar la herramienta Mogrify (desde la misma línea de comandos cuando estás en imagemagick). Ten en cuenta que esto sobreescribe las imágenes antiguas.

El comando es:

mogrify -format jpg *.png
83
83
83
2013-01-28 02:45:11 +0000

Tengo un par de soluciones más.

La solución más simple es como la mayoría ya publicada. Un simple bash para el bucle.

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

Por alguna razón tiendo a evitar los bucles en el bash así que aquí hay un enfoque más unixy xargs, usando el bash para la mezcla de nombres.

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

El que yo uso. Utiliza GNU Parallel para ejecutar múltiples trabajos a la vez, dándote un impulso en el rendimiento. Está instalado por defecto en muchos sistemas y está casi definitivamente en tu repo (es un buen programa para tener alrededor).

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

El número de trabajos por defecto es el número de procesos que tienes. Encontré un mejor uso de la CPU usando 3 trabajos en mi sistema de doble núcleo.

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

Y si quieres algunas estadísticas (un ETA, trabajos completados, tiempo medio por trabajo…)

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

También hay una sintaxis alternativa si estás usando GNU Parallel.

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

Y una sintaxis similar para algunas otras versiones (incluyendo debian).

parallel convert '{}' '{.}.jpg' -- *.png
26
26
26
2009-11-16 03:28:26 +0000

El comando convert que se encuentra en muchas distribuciones de Linux se instala como parte de la suite ImageMagick. Aquí está el código bash para ejecutar convert en todos los archivos PNG de un directorio y evitar ese problema de doble extensión:

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

Para aquellos que sólo quieren los comandos más simples:

Convertir y mantener archivos originales:

mogrify -format jpg *.png

Convertir y remover archivos originales:

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

Explicación de la conversión por lotes

Un poco tarde para la fiesta, pero para aclarar toda la confusión para alguien que no se sienta muy cómodo con Cli, aquí hay una referencia y explicación súper tonta.

Directorio de ejemplo

bar.png
foo.png
foobar.jpg

Conversión simple

Mantiene todos los archivos png originales así como crea archivos jpg.

mogrify -format jpg *.png

Resultado

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

Explicación

  • mogrify es parte de la suite de herramientas de ImageMagick para el procesamiento de imágenes.
  • mogrify procesa las imágenes en su lugar, lo que significa que el archivo original se sobrescribe, con la excepción de la opción -format. (De el sitio : This tool is similar to convert except that the original image file is overwritten (unless you change the file suffix with the -format option))
  • La opción - format especifica que se va a cambiar el formato, y el siguiente argumento debe ser el tipo (en este caso, jpg).
  • Por último, *.png son los archivos de entrada (todos los archivos que terminan en .png).

Convertir y eliminar

Convierte todos los archivos png a jpg, elimina el original.

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

Resultado

bar.jpg
foo.jpg
foobar.jpg

Explicación

  • La primera parte es exactamente igual a la anterior, creará nuevos archivos jpg.
  • El && es un operador booleano. En resumen:
  • Cuando un programa termina, devuelve un estado de salida. Un estado de 0 significa que no hay errores.
  • Ya que && realiza evaluación de cortocircuito , la parte correcta sólo se realizará si no hubo errores. Esto es útil porque puede que no quieras borrar todos los archivos originales si hubo un error al convertirlos.
  • El comando rm borra los archivos.

Fancy Stuff

Ahora aquí hay algunas cosas buenas para la gente que _se siente cómoda con el cli.

Si quieres algo de salida mientras está convirtiendo archivos:

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

Convertir todos los archivos png en todos los subdirectorios y dar salida para cada uno:

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

Convertir todos los archivos png en todos los subdirectorios, poner todos los jpgs resultantes en el directorio all, numerarlos, eliminar los archivos png originales, y mostrar la salida para cada archivo a medida que se produce:

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
8
8
8
2009-11-16 05:29:10 +0000

El comando “png2jpg” que estás buscando está en realidad dividido en dos comandos llamados pngtopnm y cjpeg, y son parte de los paquetes netpbm y libjpeg-progs, respectivamente.

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

mi solución rápidafor 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

Muchos años demasiado tarde, hay una utilidad png2jpeg específicamente para este propósito, de la cual soy autor.

Adaptación del código por @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

Para el procesamiento por lotes:

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

Terminarás con nombres de archivos como image1.png.jpg sin embargo.

Esto funcionará en bash, y tal vez en bourne. No sé sobre otras conchas, pero la única diferencia sería probablemente la sintaxis del bucle.

1
1
1
2016-09-17 02:34:45 +0000

Esto es lo que uso para convertir cuando los archivos abarcan más de un directorio. Mi original era TGA a PNG

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

El concepto es que find los archivos que necesitas, quita la extensión y vuelve a añadirla con xargs. Así que para PNG a JPG, cambiarías las extensiones y harías una cosa extra para lidiar con los canales alfa, a saber, establecer el fondo (en este ejemplo blanco, pero puedes cambiarlo) y luego aplanar la imagen

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