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.
¿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.
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
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
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
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
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
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
-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)
) - format
especifica que se va a cambiar el formato, y el siguiente argumento debe ser el tipo (en este caso, jpg). *.png
son los archivos de entrada (todos los archivos que terminan en .png). 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
&&
es un operador booleano. En resumen: 0
significa que no hay errores. &&
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. rm
borra los archivos. 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
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
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.
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