首页 > 解决方案 > 如何更有效地在 Python 中压缩 jpeg?

问题描述

我正在使用定期更新的库中的数千个大型图像文件。以下脚本完成了这项工作(平均将我的文件大小减少了约 95%),但压缩一张图像大约需要 25 秒。显然,我可以让脚本在一夜之间运行,但如果我能从这个过程中节省一些时间,那就太酷了。我主要是在脚本中寻找任何不必要的冗余或开销,可以修剪掉以加快进程。我还是 Python 的新手,所以请放轻松。

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)

谢谢!

标签: pythonpython-imaging-librarypathlib

解决方案


正如我在评论中提到的,您可以在没有 Python 的情况下执行此操作,只需在终端中使用ImageMagick即可,大多数 Linux 发行版中都包含该软件,可用于 macOS 和 Windows。

看起来您想以 40 的质量将一堆 JPEG 转换为 3,500 像素的宽度,对吗?

制作一个包含 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,则可以使用homebrew安装ImageMagickvips

brew install imagemagick
brew install vips

推荐阅读