Como posso executar o mogrify sobre os 3 milhões de arquivos JPG?

1

Eu tenho 3 milhões de arquivos JPG armazenados em um servidor Linux CentOS 6.

Eu quero alterar a qualidade para um tamanho de arquivo de 50% em mais de 1 megabyte. Eu escrevi este comando, mas recebi um erro "lista de argumentos muito longa":

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

Como posso alterar a qualidade de milhões de arquivos?

    
por Metin Çelik 24.04.2014 / 15:28

4 respostas

2

xargs suporta um argumento -n para limitar a quantidade de argumentos passados para o que for chamado:

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

Isso iniciará o mgrify uma vez por imagem. Como mogrify só pode processar um arquivo no momento, este é o caminho a percorrer.

    
por 24.04.2014 / 15:40
1

Ao usar find e xargs , não é necessário nomear os arquivos para xargs . Ele irá obter a lista de arquivos de find :

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

-n100 processará as imagens por 100s. -print0 e -0 farão o pipe funcionar mesmo se os nomes dos arquivos contiverem espaços em branco.

Você também pode chamar mogrify diretamente da pesquisa, de preferência se ele for compatível com + final para exec :

find  -type f -name '*.jpg' -size +1M -exec mogrify -quality 50 {} +
    
por 24.04.2014 / 15:35
0

Uma solução multiplataforma com Python + convert: converterá todos os arquivos PDF do diretório atual em arquivos PNG (você pode mudar para JPG se preferir) multithreadedly.

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

Isso requer Imagemagick e Ghostscript para ser instalado. Funciona no Linux / Mac OS X / Microsoft Windows.

Se você preferir adicionar o nome do arquivo em cada imagem, poderá substituir o comando em convert_to_png() por:

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))

(Veja a documentação -notate )

    
por 10.08.2017 / 03:39
0

Como mencionado em SO , você também pode fazer:

$ find -type f -name "*..jpg" -size +1M > my_jpeg.txt
$ mogrify -quality 50 @my_jpegs.txt
    
por 15.04.2019 / 12:33