如何使用 PIL 减小图像文件大小

Posted

技术标签:

【中文标题】如何使用 PIL 减小图像文件大小【英文标题】:How to reduce the image file size using PIL 【发布时间】:2012-05-23 08:41:35 【问题描述】:

我正在使用 PIL 通过将较大的图像转换为较小的图像来调整图像的大小。是否有任何标准方法可以在不损失太多质量的情况下减小图像的文件大小,假设图像的原始大小为 100KB,我想将其缩小到 5 或 10 KB,尤其是对于 png 和 jpeg 格式。

【问题讨论】:

您如何定义“过多”的质量损失?如果您想将文件大小减少 10 到 20 倍,最简单的方法是减少像素数量。将宽度和高度都减少 2/3 将为您提供大约 1/9 大小的图片。但这会让你失去很多决心。 【参考方案1】:

保存 JPEG 和 PNG 的内置参数是 optimize

 >>> from PIL import Image
 # My image is a 200x374 jpeg that is 102kb large
 >>> foo = Image.open("path\\to\\image.jpg")
 >>> foo.size
  (200,374)
 # I downsize the image with an ANTIALIAS filter (gives the highest quality)
 >>> foo = foo.resize((160,300),Image.ANTIALIAS)
 >>> foo.save("path\\to\\save\\image_scaled.jpg",quality=95)
 # The saved downsized image size is 24.8kb
 >>> foo.save("path\\to\\save\\image_scaled_opt.jpg",optimize=True,quality=95)
 # The saved downsized image size is 22.9kb

optimize 标志将对图像进行额外的传递,以找到尽可能减小其大小的方法。 1.9kb 可能看起来不多,但是超过数百/数千张图片,它可以加起来。

现在尝试将其缩小到 5kb 到 10kb,您可以在保存选项中更改质量值。 在这种情况下使用 85 而不是 95 的质量会产生: 未优化:15.1kb 优化:14.3kb 使用 75 的质量(如果省略参数,则默认)将产生: 未优化:11.8kb 优化:11.2kb

我更喜欢带有优化的质量 85,因为质量受到的影响不大,而且文件大小要小得多。

【讨论】:

ANTIALIAS 方法名称更新:从 2.7.0 开始,所有调整大小的方法都是 ANTIALIAS 并且特定 ANTIALIAS 过滤器的真实(新)名称是 LANCZOS。 (目前保留抗锯齿是为了向后兼容)pillow.readthedocs.io/en/3.0.x/releasenotes/…【参考方案2】:

假设您有一个名为 Book 的模型,上面有一个名为“cover_pic”的字段, 在这种情况下,您可以执行以下操作来压缩图像:

from PIL import Image
b = Book.objects.get(title='Into the wild')
image = Image.open(b.cover_pic.path)
image.save(b.image.path,quality=20,optimize=True)

希望它对任何偶然发现它的人有所帮助。

【讨论】:

【参考方案3】:

查看 PIL 图像模块的thumbnail 功能。您可以使用它将较小版本的文件保存为各种文件类型,如果您想尽可能多地保留质量,请考虑在这样做时使用ANTIALIAS 过滤器。

除此之外,我不确定是否有办法指定最大所需大小。当然,您可以编写一个函数,尝试以不同的质量保存文件的多个版本,直到满足特定大小,丢弃其余的并为您提供所需的图像。

【讨论】:

有没有办法通过保持尺寸不变来减小文件大小。对于 png 格式。 如果您想保持相同的尺寸,您唯一可以尝试的另一件事是在保存图像时设置质量设置。查看this answer 但质量属性对 png 格式没有影响。即使我改变质量,文件大小保持不变。 那我恐怕不知道。由于其压缩格式,PNG 传统上的尺寸较大。 PNG是必须的吗?如果没有,您是否考虑过尝试 GIF? 对于 PNG,将图像转换为使用较小的调色板。写入文件时使用值 【参考方案4】:

PIL 中的主要图片管理器是PILImage 模块。

from PIL import Image
import math

foo = Image.open("path\\to\\image.jpg")
x, y = foo.size
x2, y2 = math.floor(x-50), math.floor(y-20)
foo = foo.resize((x2,y2),Image.ANTIALIAS)
foo.save("path\\to\\save\\image_scaled.jpg",quality=95)

您可以将optimize=True 添加到您想要进一步减小大小的参数中,但优化仅适用于JPEG 和PNG。 对于其他图像扩展,您可以降低新保存图像的质量。 您可以通过删除一些代码并定义图像大小来更改新图像的大小,只有仔细查看代码才能弄清楚如何做到这一点。 我定义了这个尺寸:

x, y = foo.size
x2, y2 = math.floor(x-50), math.floor(y-20)

只是为了向您展示(几乎)通常对水平图像进行的处理。 对于垂直图像,您可能会这样做:

x, y = foo.size
x2, y2 = math.floor(x-20), math.floor(y-50)

。请记住,您仍然可以删除那段代码并定义新的大小。

【讨论】:

【参考方案5】:

您可以调整图片大小,也可以降低图片质量。 附上几个例子:

Python PIL 调整图像大小

from PIL import Image
WIDTH = 1020
HEIGHT = 720
img = Image.open("my_image.jpg")
resized_img = img.resize((WIDTH, HEIGHT))
resized_img.save("resized_image.jpg")

更改图像分辨率枕头

from PIL import Image
size = 7016, 4961
im = Image.open("my_image.png")
im_resized = im.resize(size, Image.ANTIALIAS)
im_resized.save("image_resized.png", "PNG")

或者你可以使用

im_resized.save("image_resized.png", quality=95, optimize=True)

【讨论】:

【参考方案6】:

如果你有一个胖 png(400x400 等为 1MB):

__import__("importlib").import_module("PIL.Image").open("out.png").save("out.png")

【讨论】:

以上是关于如何使用 PIL 减小图像文件大小的主要内容,如果未能解决你的问题,请参考以下文章

如何将 jpeg 大小减小到“所需大小”?

如何在本机反应中减小图像文件大小?

如何在php中减小图像大小?

PIL如何根据图像大小缩放文本大小

如何在swift ios中减小图像的大小[重复]

如何在上传到服务器之前减小图像文件大小