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

Yas*_*mar 54 python compression image python-imaging-library

我正在使用PIL通过将较大的图像转换为较小的图像来调整图像的大小.有没有任何标准的方法来减少图像的文件大小而不会过多地损失质量,让我们说图像的原始大小是100KB,我想把它降低到5或10 KB,特别是对于png和jpeg格式.

Rya*_*n G 96

用于保存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
Run Code Online (Sandbox Code Playgroud)

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

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

我更喜欢质量85优化,因为质量不会受到太大影响,文件大小要小得多.

  • ANTIALIAS 方法名称更新:从 2.7.0 开始,所有调整大小的方法都是 ANTIALIAS,特定 ANTIALIAS 过滤器的真实(新)名称是 LANCZOS。(目前为了向后兼容而保留 antialias) https://pillow.readthedocs.io/en/3.0.x/releasenotes/2.7.0.html#antialias-renamed-to-lanczos (5认同)

小智 10

假设您有一个名为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)
Run Code Online (Sandbox Code Playgroud)

希望它能帮助任何绊倒它的人.


Cry*_*ite 7

参见PIL的Image Module的缩略图功能。您可以使用它来将较小版本的文件保存为各种文件类型,如果您想尽可能保留质量,请考虑使用过滤器ANTIALIAS

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

  • 但质量属性对于 png 格式没有区别。即使我更改质量,文件大小也保持不变。 (3认同)
  • 有没有办法通过保持尺寸恒定来减少文件大小,特别是。对于 png 格式。 (2认同)
  • 如果您想保持相同的尺寸,您唯一可以尝试的就是在保存图像时设置质量设置。查看[这个答案](http://stackoverflow.com/a/1405701/369878) (2认同)
  • 通过“pngcrush”实用程序运行 PNG。不过,根据你从哪里得到它们,它们可能已经被压碎了,所以这没有帮助。不过,它对于您自己创建的内容非常有效。 (2认同)

Son*_*ong 6

主要的图像管理器PILPILImage模块。

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)
Run Code Online (Sandbox Code Playgroud)

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

x, y = foo.size
x2, y2 = math.floor(x-50), math.floor(y-20)
Run Code Online (Sandbox Code Playgroud)

只是为了向您展示(几乎)通常对水平图像所做的操作。对于垂直图像,您可以这样做:

x, y = foo.size
x2, y2 = math.floor(x-20), math.floor(y-50)
Run Code Online (Sandbox Code Playgroud)

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


oru*_*kin 5

该脚本将减小图像的宽度和高度,with saving it's proportion并且还会减小尺寸

two options,他们在做同样的逻辑first one is how i did in django project,,second is on pure python

您可以更改TARGET_WIDTH为您需要的宽度

图像保存后django models.py,将再次处理

from PIL import Image

class Theme(models.Model):
    image = models.ImageField(upload_to='theme_image/')
    
    def save(self, *args, **kwargs):
        super().save(*args, **kwargs)
        this_image = Image.open(self.image.path)
        width, height = this_image.size
        TARGET_WIDTH = 500
        coefficient = width / 500
        new_height = height / coefficient
        this_image = this_image.resize((int(TARGET_WIDTH),int(new_height)),Image.ANTIALIAS)
        this_image.save(self.image.path,quality=50)
Run Code Online (Sandbox Code Playgroud)

没有Django foo.py

from PIL import Image

this_image = Image.open("path\to\your_image.jpg")
width, height = this_image.size
TARGET_WIDTH = 500
coefficient = width / 500
new_height = height / coefficient
this_image = this_image.resize((int(TARGET_WIDTH),int(new_height)),Image.ANTIALIAS)
this_image.save("path\where\to_save\your_image.jpg",quality=50)
Run Code Online (Sandbox Code Playgroud)

  • python 成像库 (`PIL`) 已被折旧。请改用“枕头”。 (3认同)
  • 还有一些事情 - 为了让 Django Cleanup 工作,您必须在保存完成后关闭图像进程。你需要...“this_image.close()”和“self.image.close()” (2认同)
  • 对于 Pillow 9.2.0,您必须执行 PIL.Image.open(self.image)... 和 PIL.Image.ANTIALIAS (2认同)