Как я могу сжать JPEG в Python более эффективно? - PullRequest
0 голосов
/ 22 января 2020

Я работаю с тысячами больших файлов изображений в регулярно обновляемой библиотеке. Следующий скрипт выполняет эту работу (в среднем размер файла уменьшается на 95%), но мне нужно около 25 секунд, чтобы сжать одно изображение. Очевидно, что я могу просто позволить скрипту работать в одночасье, но было бы здорово, если бы я мог немного сбрить этот процесс. В основном я ищу любые ненужные избыточности или накладные расходы в сценарии, которые можно обрезать, чтобы ускорить процесс. Я все еще новичок в Python, так что go легко для меня.

from PIL import Image
from pathlib import Path
import os, sys
import glob

root_dir = "/.../"

basewidth = 3500

for filename in glob.iglob(root_dir + '*.jpg', recursive=True):
    p = Path(filename)
    img = p.relative_to(root_dir)
    new_name = (root_dir + 'compressed/' + str(img))
    print(new_name)
    im = Image.open(filename)
    wpercent = (basewidth/float(im.size[0]))
    hsize = int((float(im.size[1])*float(wpercent)))
    im = im.resize((basewidth,hsize), Image.ANTIALIAS)
    im.save(new_name, 'JPEG', quality=40)

Спасибо!

1 Ответ

1 голос
/ 05 февраля 2020

Как я уже упоминал в комментариях, вы можете сделать это без Python, просто в Терминале с ImageMagick , который включен в большинство Linux дистрибутивов и доступен для macOS и Windows .

Похоже, что вы хотите конвертировать несколько JPEG-файлов в ширину 3500 пикселей с качеством 40, верно?

Создайте тестовый каталог с примерно 100 JPEG-файлами в нем - КОПИЯ недрагоценных файлов, с которыми вы можете поиграть и поэкспериментировать. Эта команда должна преобразовать один единственный JPEG, поэтому попробуйте сначала:

magick input.jpg -quality 40 -resize 3500x result.jpg

Если это выглядит правильно, эта команда будет делать то же самое для всех файлов JPEG в текущем каталоге и сохранять результаты в подкаталоге с именем processed:

mkdir processed
magick mogrify -path processed -resize 3500x -quality 40 *.jpg

Если это выглядит правильно, мы можем распараллелить это следующим образом ... дайте мне знать, как это происходит.


Вы также можете сделать это с помощью libvips , Итак, для обработки одного изображения:

vipsthumbnail input.jpg -o result.jpg[Q=40] --size 3500x

И попробуйте это на всех 100 изображениях с помощью:

for f in *.jpg ; do
    echo "Processing $f"
    vipsthumbnail "$f" -o processed/"$f"[Q=40] --size 3500x
done

Если это быстрее, мы можем продолжить это параллельно.


Если вы используете macOS, вы можете установить ImageMagick и vips с homebrew :

brew install imagemagick
brew install vips
...