8

Desidero ridimensionare un numero elevato (circa 5200) di file di immagine (formato PPM, ogni 5 MB di dimensione) e salvarli in formato PNG utilizzando convert.ImageMagick: come ottenere un utilizzo di memoria ridotto durante il ridimensionamento di un numero elevato di file di immagine?

Versione corta:

convert colpi fino 24 GB di memoria, anche se io uso la sintassi che racconta convert per elaborare i file di immagine consecutivamente.

Versione lunga:

Per quanto riguarda più di 25 GB di dati di immagine, immagino che non dovrei elaborare tutti i file contemporaneamente. Ho cercato la documentazione ImageMagick su come elaborare i file di immagini in sequenza e ho found:

è più veloce e meno intensivo di risorse per ridimensionare ogni immagine è lettura:

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

anche , the tutorial states:

Ad esempio anziché ...

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

che legge tutti i file TIFF in un primo momento, poi li ridimensiona. È possibile invece fare ...

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

Questo leggerà ogni immagine, e ridimensionarle, prima di procedere alla l'immagine successiva. Con conseguente riduzione dell'utilizzo della memoria ed eventualmente lo impedisce lo scambio del disco (thrashing), quando vengono raggiunti i limiti di memoria.

Quindi, questo è quello che sto facendo:

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

Secondo la documentazione, si deve trattare ogni file di immagine ad uno ad uno: leggere, ridimensionare, scrivere. Lo sto facendo su una macchina con 12 core reali e 24 GB di RAM. Tuttavia, durante i primi due minuti, l'utilizzo della memoria del processo convert aumenta a circa il 96%. Rimane lì un po '. L'utilizzo della CPU è al massimo. Un po 'più a lungo e il processo muore, solo dicendo:

Ucciso

A questo punto, nessun file di output sono stati prodotti. Sono su Ubuntu 10.04 e 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 

Sembra convert cerca di leggere tutti i dati prima di avviare la conversione. Quindi, c'è un bug in convert, un problema con la documentazione o non ho letto correttamente la documentazione.

Cosa c'è che non va? Come posso ottenere un utilizzo di memoria basso durante il ridimensionamento di un numero elevato di file di immagine?

BTW: una soluzione rapida sarebbe il loop dei file usando la shell e invocare convert per ogni file in modo indipendente. Ma mi piacerebbe capire come ottenere lo stesso con ImageMagick puro.

Grazie!

+1

Se si prova qualcosa come 'trovare. -name "* .ppm" -exec convert '{} [1280x1280]' pngs /% 05d.png \; 'funziona? 'find -exec' elencherà tutti i file e per ognuno di essi esegue il comando dato in argomento. – Flinth

+0

@epingle: In linea di principio funziona (come ho detto nell'ultima parte della mia domanda). Fare qualcosa del genere è anche la mia soluzione temporanea. Tuttavia, deve anche (dovrebbe) funzionare con ImageMagick puro. (Nota che la tua soluzione particolare non funzionerebbe, dato che il contatore di file '% 05d' sarebbe sempre zero). –

+0

Ok scusa, non ho visto la fine del tuo messaggio o che la% 05d era un contatore per te – Flinth

risposta

5

Senza l'accesso diretto al tuo sistema è davvero difficile aiutarti a eseguire il debug di questo.

Ma si può fare tre cose per aiutare se stessi restringendo questo problema:

  1. Aggiungi -monitor come primo argomento di comando per vedere più dettagli su quello che sta succedendo.

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

  3. temporaneamente, non utilizzare '* .ppm [1280x1280]' come argomento, ma l'uso 'una * .ppm [1280x1280]', invece. Lo scopo è limitare l'espansione di caratteri jolly (o qualche altro modo adatto per ottenere lo stesso risultato) a solo poche partite, invece di tutte le possibili corrispondenze.

Se si esegue "2." dovrai fare '3.' altrimenti sarai sopraffatto dalla massa dell'output. (Anche il sistema sembra non essere in grado di elaborare il pieno jolly in ogni caso, senza dover uccidere il processo ...)

Se non si trova una soluzione, poi ...

  1. .. .registrare un nome utente a the official ImageMagick bug report forum.
  2. ... segnala il tuo problema lì per vedere se loro può aiutarti (questi ragazzi sono piuttosto cordiali e reattivi se lo chiedi educatamente).
2

avuto lo stesso problema, a quanto pare è perché ImageMagick creare file temporanei nella directory/tmp, che è spesso montato come tmpfs.

Basta spostare il tuo tmp da qualche altra parte.

Ad esempio:

  • creare una directory "tmp" su un grande disco esterno

    mkdir -m777 /media/huge_device/tmp

  • assicurarsi che le autorizzazioni siano impostate a 777

    chmod 777 /media/huge_device/tmp

  • come root, montarlo in sostituzione al vostro/tmp

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

Nota: Dovrebbe essere possibile utilizzare la variabile d'ambiente TMP a fare lo stesso trucco.

0

Vorrei andare con GNU Parallel se si dispone di 12 core - qualcosa di simile, che funziona molto bene. Come fa solo 12 immagini alla volta, pur mantenendo la numerazione dei file di output, utilizza solo una RAM minima.

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 

Note

-scene consente di impostare il contatore scena, che esce nel vostro %05d parte.

--eta prevede quando sarà terminato il lavoro (tempo stimato di arrivo).

-j 12 esegue 12 lavori in parallelo alla volta.

Problemi correlati