Come posso eseguire il mogrify sui 3 milioni di file JPG?


1

Ho 3 milioni di file JPG memorizzati in un server Linux CentOS 6.

Voglio cambiare la qualità in% 50 dimensioni del file oltre 1 megabyte. Ho scritto questo comando ma ho ricevuto un errore "Elenco argomenti troppo lungo":

$ find -type f -name "*..jpg" -size +1M | xargs mogrify -quality 50 *.jpg
bash: /usr/bin/xargs: Argument list too long

Come posso cambiare la qualità di milioni di file?


2
Perché aggiungi *.jpga xargs? Otterrà i file da find.
Choroba,

Risposte:


2

xargssupporta un -nargomento per limitare la quantità di argomenti passati a tutto ciò che chiama:

find -type f -name '*.jpg' -size +1M -print0 | xargs -0 -n1 mogrify -quality 50

Questo avvierà il mogrify una volta per immagine. Poiché mogrify può elaborare solo un file alla volta, questa è la strada da percorrere.


mogrifyLa documentazione di mostra esempi con *.jpg.
Choroba,

Ah, mi sono fidato ciecamente della manpage: "SYNOPSIS mogrify [opzioni] input-file" - indicando che supporta solo uno.
Dennis Kaarsemaker,

1

Quando si utilizza finde xargs, non è necessario assegnare un nome ai file xargs. Otterrà l'elenco dei file da find:

find -print0 -type f -name '*.jpg' -size +1M | xargs -0 -n100 mogrify -quality 50

-n100elaborerà le immagini di 100 secondi. -print0e -0farà funzionare la pipa anche se i nomi dei file contengono spazi bianchi.

Puoi anche chiamare mogrifydirettamente da find, idealmente se supporta il +finale per exec:

find  -type f -name '*.jpg' -size +1M -exec mogrify -quality 50 {} +

Ciò renderà ancora troppo lungo l'elenco degli argomenti nel primo comando, se tutti vengono passati a xargs in uno. Inoltre, è necessario findeseguire il pipe da a xargscon find ... -print0 | xargs -0.
slhck,

Beh, per fortuna, find posso fare tutto . : D Invece di terminare il comando -exec con +, può anche essere terminato con ;. Questo esegue il comando una volta per risultato. Non dimenticare di scappare ;!
Daniel B,

@DanielB: qual è il vantaggio di ;over +in questo caso?
Choroba,

1
Non risulta in una riga di comando troppo lunga. Anche se findpotrebbe già aggirare questo, chi lo sa. È adatto anche per comandi che non accettano input batch.
Daniel B,

Bene, anche se può essere un po 'spam, ho scoperto xargse find, in effetti, sono abbastanza intelligente da dividere automaticamente la raccolta di argomenti.
Daniel B,

0

Una soluzione multipiattaforma con Python + convert: convertirà tutti i file PDF della directory corrente in file PNG (puoi cambiare in JPG se preferisci) in modo multithread.

from __future__ import print_function
import os
import glob
import multiprocessing      

def convert_to_png(pdf_filepath):
    '''
    Convert PDF file to PNG file
    '''
    png_filepath = '{0}.png'.format(pdf_filepath[:-4])
    print('pdf_filepath: {0}'.format(pdf_filepath))
    print('png_filepath: {0}'.format(png_filepath))
    command = 'convert -background white -alpha off -geometry 1600x1600 -density 200x200 -quality 100 -resize 800x {0} {1}'.format(pdf_filepath, png_filepath)
    print(command)
    os.system(command)

def main():
    pdf_filepaths = glob.iglob(os.path.join('.','*.pdf'))
    pool = multiprocessing.Pool(processes=4)
    pool.map(convert_to_png, pdf_filepaths)
    pool.close()
    pool.join()   
    print('done')

if __name__ == "__main__":
    main()
    #cProfile.run('main()') # if you want to do some profiling

Ciò richiede l' installazione di Imagemagick e Ghostscript . Funziona su Linux / Mac OS X / Microsoft Windows.

Se si preferisce aggiungere il nome file su ciascuna immagine, è possibile sostituire il comando convert_to_png()con:

command = 'convert  -background white -alpha off -geometry 1600x1600 -density 200x200 -quality 100 -annotate +50+50 {2} -resize 800x {0} {1}'.format(pdf_filepath, png_filepath, os.path.basename(pdf_filepath))

(Vedi la documentazione -annotata )


0

Come accennato in SO , puoi anche fare:

$ find -type f -name "*..jpg" -size +1M > my_jpeg.txt
$ mogrify -quality 50 @my_jpegs.txt
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.