8

me gustaría cambiar el tamaño de un número grande (aproximadamente 5200) de archivos de imagen (formato PPM, cada 5 MB de tamaño) y guardarlos en formato PNG utilizando convert.ImageMagick: ¿cómo lograr un bajo uso de memoria al cambiar el tamaño de una gran cantidad de archivos de imagen?

versión corta:

convert golpes de hasta 24 GB de memoria aunque yo uso la sintaxis que dice convert para procesar archivos de imágenes consecutivamente.

Versión larga:

En cuanto a más de 25 GB de datos de imagen, supongo que no debería procesar todos los archivos al mismo tiempo. He buscado en la documentación de ImageMagick sobre cómo procesar archivos de imágenes consecutivamente y yo found:

es más rápido y menos recursos para cambiar el tamaño de cada imagen es lectura:

$ convert '*.jpg[120x120]' thumbnail%03d.png

también , the tutorial states:

Por ejemplo, en lugar de ...

montage '*.tiff' -geometry 100x100+5+5 -frame 4 index.jpg

el que lee todos los archivos TIFF en primer lugar, a continuación, los redimensiona. Puede lugar hacer ...

montage '*.tiff[100x100]' -geometry 100x100+5+5 -frame 4 index.jpg

Esto permitirá la lectura de cada imagen, y el tamaño de ellos, antes de proceder a la siguiente imagen. Resultando en un uso de memoria mucho menor, y posiblemente previene el intercambio de disco (agitación), cuando se alcanzan los límites de memoria.

Por lo tanto, esto es lo que estoy haciendo:

$ convert '*.ppm[1280x1280]' pngs/%05d.png 

De acuerdo con los documentos, se debe tratar a cada archivo de imagen de uno en uno: leer, cambiar el tamaño, escribir. Estoy haciendo esto en una máquina con 12 núcleos reales y 24 GB de RAM. Sin embargo, durante los primeros dos minutos, el uso de memoria del proceso convert crece a aproximadamente 96%. Se queda allí un tiempo. El uso de la CPU es máximo. Un poco más y el proceso muere, sólo decir:

Killed

En este momento, no hay archivos de salida se han producido. Estoy en Ubuntu 10.04 y convert --version dice:

Version: ImageMagick 6.5.7-8 2012-08-17 Q16 http://www.imagemagick.org 
Copyright: Copyright (C) 1999-2009 ImageMagick Studio LLC 
Features: OpenMP 

Parece que convert intenta leer todos los datos antes de iniciar la conversión. Entonces, o bien hay un error en convert, un problema con la documentación o no leí la documentación correctamente.

¿Qué pasa? ¿Cómo puedo lograr un bajo uso de memoria al cambiar el tamaño de esta gran cantidad de archivos de imagen?

BTW: una solución rápida sería simplemente recorrer los archivos utilizando el shell e invocar convert para cada archivo de forma independiente. Pero me gustaría entender cómo lograr lo mismo con ImageMagick puro.

Gracias!

+1

Si intenta algo como 'encontrar. -name "* .ppm" -exec convert '{} [1280x1280]' pngs /% 05d.png \; '¿esto funciona? 'find -exec' listará todos los archivos y para cada uno de ellos ejecuta el comando dado en el argumento. – Flinth

+0

@epingle: En principio, esto funciona (como dije en la última parte de mi pregunta). Hacer algo así también es mi solución temporal. Aún así, también tiene que (debería) funcionar con ImageMagick puro. (Tenga en cuenta que su solución particular no funcionaría, ya que el contador de archivos '% 05d' siempre sería cero). –

+0

Lo siento, no vi el final de su mensaje o que el% 05d era un contador para usted – Flinth

Respuesta

5

Sin tener acceso directo a su sistema, es realmente difícil ayudarlo a depurar esto.

Pero se puede hacer tres cosas para ayudarse a sí mismo la reducción a este problema:

  1. Añadir -monitor como primer argumento de línea de comandos para ver más detalles acerca de lo que está pasando.

  2. (opcional) añadir -debug all -log "domain: %d +++ event: %e +++ function: %f +++ line: %l +++ module: %m +++ processID: %p +++ realCPUtime: %r +++ wallclocktime: %t +++ userCPUtime: %u \n\r"

  3. Temporalmente, no utilice '* .ppm [1280x1280]' como un argumento, pero el uso 'a * .ppm [1280x1280]' en su lugar. El objetivo es limitar la expansión de su comodín (u otra forma adecuada de lograr el mismo) a solo unos pocos partidos, en lugar de todas las posibles coincidencias.

Si haces '2.' deberás hacer '3.' De lo contrario, la masa de producción te abrumará. (También el sistema parece no ser capaz de procesar el comodín lleno de todos modos sin tener que matar el proceso ...)

Si no encuentra una solución, entonces ...

  1. .. .registre un nombre de usuario al the official ImageMagick bug report forum.
  2. ... informe su problema allí para ver si ellos pueden ayudarlo (estos tipos son bastante amables y receptivos si se lo pide educadamente).
2

dieron el mismo tema, parece que es porque ImageMagick crear archivos temporales en el directorio/tmp, que se monta a menudo como un tmpfs.

Simplemente mueva su tmp a otro lugar.

Por ejemplo:

  • crear un directorio "tmp" en una unidad externa grande

    mkdir -m777 /media/huge_device/tmp

  • Asegúrese de que los permisos se establecen a 777

    chmod 777 /media/huge_device/tmp

  • como root, monte en sustitución a las/tmp

    mount -o bind /media/huge_device/tmp /tmp

Nota: Debería ser posible utilizar la variable de entorno TMP para hacer el mismo truco.

0

Me gustaría ir con GNU Parallel si tienes 12 núcleos, algo como esto, que funciona muy bien. Como solo hace 12 imágenes a la vez, conservando la numeración de los archivos de salida, solo utiliza una cantidad mínima de RAM.

scene=0 
for f in *.ppm; do 
    echo "$f" $scene 
    ((scene++)) 
done | parallel -j 12 --colsep ' ' --eta convert {1}[1280x1280] -scene {2} pngs/%05d.png 

Notas

-scene le permite ajustar el contador de escenas, que sale en su parte %05d.

--eta predice cuándo terminará su trabajo (Hora estimada de llegada).

-j 12 ejecuta 12 trabajos en paralelo a la vez.

Cuestiones relacionadas