在 django 上无损压缩图像
Posted
技术标签:
【中文标题】在 django 上无损压缩图像【英文标题】:Losslessly compressing images on django 【发布时间】:2016-01-09 17:40:08 【问题描述】:我正在进行优化,Google 建议对图像进行无损压缩,正在寻找一种在 Django 中实现此功能的方法。
这是他们指定的图像,我认为要有效地完成它需要在系统范围内实现,可能使用中间件类想知道是否有人以前做过。这是页面速度的谷歌分析链接https://developers.google.com/speed/pagespeed/insights/?url=www.kenyabuzz.com
优化图片 正确格式化和压缩图像可以节省许多字节的数据。 优化以下图片,使其大小减少 627.3KiB(减少 74%)。
Losslessly compressing http://www.kenyabuzz.com/media/uploads/clients/kenya_buzz_2.jpg could save 594.3KiB (92% reduction).
Losslessly compressing http://www.kenyabuzz.com/media/uploads/clients/new_tribe_2.jpg could save 25KiB (44% reduction).
Losslessly compressing http://www.kenyabuzz.com/…a/uploads/clients/EthiopianAirlines2.jpg could save 3KiB (22% reduction).
Losslessly compressing http://www.kenyabuzz.com/static/kb/images/Nightlife.Homepage.jpg could save 1.3KiB (2% reduction).
Losslessly compressing http://www.kenyabuzz.com/static/kb/img/social/blog.png could save 1.1KiB (43% reduction).
Losslessly compressing http://www.kenyabuzz.com/static/kb/img/social/twitter.png could save 969B (52% reduction).
Losslessly compressing http://www.kenyabuzz.com/…der-Board---Email-Signature--Neutral.jpg could save 920B (2% reduction).
Losslessly compressing http://www.kenyabuzz.com/static/kb/img/social/youtube.png could save 757B (31% reduction).
【问题讨论】:
在您引用的页面中点击链接developers.google.com/speed/docs/insights/OptimizeImages 可以提供大量信息。你读过吗? 是的,我做到了,但他们没有提供有关如何使用 python 或 Django 实现相同功能的信息。我用谷歌搜索了“Losslesly compressing images django”,但没有得到任何相关信息。 为什么在 Django 中这样做 - 谷歌优化页面中有一个链接允许谷歌为你做这件事。抓取这些图像,上传到服务器,收集静态图像,然后完成。 这个项目直接在模型上启用了其中的几个选项。 github.com/un1t/django-resized 【参考方案1】:我没有这方面的经验,但是,picopt
看起来很全面。它广泛依赖外部工具来执行优化,因此可能难以在受限或托管的服务器环境中进行设置。
除此之外,请尝试使用谷歌搜索“python 图像优化”。还有一些其他链接表明基于 PIL 的解决方案可能是可能的,例如:
-
How to reduce the image file size using PIL
Image Optimization (Google App Engine with Python)
【讨论】:
【参考方案2】:你应该试试Django Easy Thumbnails app,它有一些选项可以添加后处理来优化上传的图片:PostProcessor documentation
我在多个项目的生产中使用它。 它运行良好,图像尺寸肯定更小,页面加载速度快得多。
【讨论】:
【参考方案3】:无损压缩 http://www.kenyabuzz.com/media/uploads/clients/kenya_buzz_2.jpg 可以节省 594.3KiB(减少 92%)。
首先,日志中的信息不是很准确。
只有在原始图像未压缩且颜色数量非常少(理想情况下少于 256)时,才能实现 92% 的无损缩减。
无损压缩涉及减少图像的“位深度”,即如果颜色少于 256 种,则将 24 位图像转换为 8 位,这意味着您每像素节省 16 位。但对于您链接的图片来说,这似乎是不可能的,因为它们有超过 256 种颜色。
其次,您可以使用有损压缩格式“不会降低质量” - 差异是如此微妙,人眼甚至都不会注意到。
阅读this answer 和this answer 了解更多信息。真的,请阅读它们,两者都是与此问题相关的出色答案。
所以,我从您正在优化的网站下载了一张图片,链接:http://www.kenyabuzz.com/media/uploads/clients/kenya_buzz_2.jpg
我打开我的 Python 控制台并写了这个:
>>> from PIL import Image
>>> # Open the image
>>> im = Image.open("kenya_buzz_2.jpg")
>>> # Now save it
>>> im.save("kenya_buzz_compressed.jpg", format="JPEG", quality=70)
这在我的磁盘上创建了一个新图像。下面是两张图片。
原始 (655.3kB)
压缩(22.4kB ~96% 减少 @ quality=70)
您可以使用quality
选项。比如,80
的值将为您提供质量更好的图像,但尺寸稍大。
在 Django 中压缩图像
由于这是一个非常流行的问题,我决定添加一个示例代码来在 Django 中压缩图像。
此代码适用于 Django >= 1.7。
from io import BytesIO
from PIL import Image
from django.core.files import File
def compress(image):
im = Image.open(image)
# create a BytesIO object
im_io = BytesIO()
# save image to BytesIO object
im.save(im_io, 'JPEG', quality=70)
# create a django-friendly Files object
new_image = File(im_io, name=image.name)
return new_image
这就是您可以在 Django 模型(或任何地方)中使用上述 compress
函数的方法:
# models.py
class MyModel(...):
image = models.ImageField(...)
def save(self, *args, **kwargs):
# call the compress function
new_image = compress(self.image)
# set self.image to new_image
self.image = new_image
# save
super().save(*args, **kwargs)
基本上就是这样。这是相当基本的代码。您可以通过仅在图像更改而不是每次保存模型时压缩图像来改进代码。
【讨论】:
没错,我会在上传部分使用它,或者像 triage 这样的纯静态图像。 它对我不起作用。我试图缩小 1MB 的图像,但我得到了 1.9MB 的新图像:| @Overflow012 您设置的quality
值是否大于95
?众所周知,这会增加文件大小。
@xyres,不,我正在使用quality=70
@xyres 但我不想将新图像保存在我的磁盘中,我只想在浏览器中显示压缩图像。以上是关于在 django 上无损压缩图像的主要内容,如果未能解决你的问题,请参考以下文章
Google 的 Page Speed 无损图像压缩是如何工作的?
图像压缩基于matlab GUI DCT图像无损压缩含Matlab源码 726期