<blockquote>
<p>Losslessly compressing <a href="http://www.kenyabuzz.com/media/uploads/clients/kenya_buzz_2.jpg" rel="noreferrer">http://www.kenyabuzz.com/media/uploads/clients/kenya_buzz_2.jpg</a> could save 594.3KiB (92% reduction).</p>
</blockquote>
<p>首先,日志中的信息是相当误导的,因为不可能使用无损格式将图像压缩92%(除了某些情况,如单色图像、基本几何形状如正方形等)。阅读<a href="https://stackoverflow.com/a/419602/1925257">this answer</a>和<a href="https://stackoverflow.com/a/7752936/1925257">this answer</a>了解更多信息。真的,一定要读它们,它们都是很好的答案。</p>
<p>第二,你可以使用有损压缩格式而不损失质量,这种差异是如此微妙,人眼甚至没有注意到。</p>
<hr/>
<p>所以,我从你正在优化的网站下载了一张图片,链接是:<a href="http://www.kenyabuzz.com/media/uploads/clients/kenya_buzz_2.jpg" rel="noreferrer">http://www.kenyabuzz.com/media/uploads/clients/kenya_buzz_2.jpg</a></p>
<p>我打开我的Python控制台,写了这样一段话:</p>
<pre><code>>>> 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)
</code></pre>
<p>这在我的磁盘上创建了一个新图像。下面是两张图片。</p>
<p><strong>原件(655.3kB)</strong></p>
<p><a href="https://i.stack.imgur.com/hzwPB.jpg" rel="noreferrer"><img src="https://i.stack.imgur.com/hzwPB.jpg" alt="original image"/></a></p>
<hr/>
<p><strong>压缩(22.4kB~96%,质量=70)</strong></p>
<p><a href="https://i.stack.imgur.com/cF2j1.jpg" rel="noreferrer"><img src="https://i.stack.imgur.com/cF2j1.jpg" alt="compressed image using Python"/></a></p>
<hr/>
<p>您可以使用<code>quality</code>选项。例如,<code>80</code>的值将为您提供更好的图像质量,但大小稍大一些。</p>
<hr/>
<h2>Django中的图像压缩</h2>
<p>由于这是一个非常流行的问题,我决定添加一个示例代码来压缩Django中的图像。</p>
<p>此代码适用于Django>;=1.7。</p>
<pre><code>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
</code></pre>
<p>这就是如何在Django模型(或任何地方)中使用上述<code>compress</code>函数的方法:</p>
<pre><code># 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)
</code></pre>
<p>基本上就是这样。这是相当基本的代码。您可以只在图像更改时压缩图像,而不是每次保存模型时压缩图像,从而改进代码。</p>