简体   繁体   English

如何更有效地在 Python 中压缩 jpegs?

[英]How can I compress jpegs in Python more efficiently?

I'm working with thousands of large image files in a regularly updated library.我正在使用定期更新的库中的数千个大型图像文件。 The following script does the job (on average reduces my file size ~95%) but costs me around 25 seconds to compress one image.以下脚本完成了这项工作(平均减少了我的文件大小约 95%),但我压缩一张图像大约需要 25 秒。 Obviously, I can just let the script run overnight, but it would be cool if I can shave some time off this process.显然,我可以让脚本在一夜之间运行,但如果我能在这个过程中节省一些时间,那就太酷了。 I'm mostly looking for any unnecessary redundancies or overhead in the script that can be trimmed out to speed up the process.我主要是在脚本中寻找任何不必要的冗余或开销,这些冗余或开销可以被修剪以加快进程。 I'm still new to Python, so go easy on me.我还是 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)

Thanks!谢谢!

As I mentioned in the comments, you can do this without Python, just in the Terminal with ImageMagick , which is included in most Linux distros and is available for macOS and Windows.正如我在评论中提到的,您可以在没有 Python 的情况下执行此操作,只需在带有ImageMagick的终端中即可,大多数 Linux 发行版都包含它,可用于 macOS 和 Windows。

It looks like you want to convert a bunch of JPEGs to a width of 3,500 pixels at a quality of 40, correct?看起来您想以 40 的质量将一堆 JPEG 转换为 3,500 像素的宽度,对吗?

Make a testing directory with 100 or so JPEGs in it - a COPY of non-precious files that you can play around and experiment on.请用100左右,它的JPEG测试目录-非贵重文件,你可以玩和实验上的副本 This command should convert one single JPEG, so try that first:此命令应转换单个 JPEG,因此请先尝试:

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

If that looks correct, this command will do exactly the same to all the JPEGs in the current directory and save the results in a subdirectory called processed :如果看起来正确,此命令将对当前目录中的所有 JPEG 执行完全相同的操作,并将结果保存在名为processed的子目录中:

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

If that looks correct, we can parallelise it next.. let me know how it goes.如果这看起来正确,我们接下来可以并行化它..让我知道它是怎么回事。


You can also do it with libvips .你也可以用libvips做到这libvips So, to process one image:因此,要处理一张图像:

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

And try that on all 100 images with:并在所有 100 张图像上尝试使用:

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

If that is faster, we can pursue that in parallel.如果速度更快,我们可以同时进行。


If you are on macOS, you can install ImageMagick and vips with homebrew :如果您使用的是 macOS,则可以使用homebrew安装ImageMagickvips

brew install imagemagick
brew install vips

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM