django在保存图像的同时压缩图像示例代码详解

作者:mindg.cn 时间:2021-09-21 15:42:46 

假设我们有一个非常简单的Post模型,它将是一个图像及其描述,


from django.db import models

class Post(models.Model):
text = models.TextField()
image = models.ImageField(upload_to='images/')

但是我们要优化图像大小,这将由我们Post的image字段指出。 这样做有充分的理由-它有助于更快地加载网站/应用程序并减少我们的服务器存储。 在使用Django之前,首先让我们简单介绍一下使用Pillow进行图像压缩的概述。

使用Pillow压缩图像

Pillow是用于图像相关操作的出色Python软件包。 Image类带有用于图像io和操作的方法。 Image.open从文件路径或文件对象读取图像。 Image类的save方法将质量作为以jpg格式保存图像的可选参数,范围为1到95,此参数的默认值为75,并且设置质量大于95会导致图像尺寸大于 原本的。


from PIL import Image
im = Image.open('/some/path/to/image')
im.save('/desired/path/new_image_name.jpg', quality=70)
im.close()

使用quality参数不是减小大小的唯一方法。 例如,您可以将其与调整图像大小相结合,以获得更小的图像尺寸。

利用Django signals

信号允许某些发送者通知一组接收者已经采取了某些措施。

Django带有许多内置信号,目前,我们对django.db.models.signals.pre_save信号感兴趣,该信号将在调用模型的save()方法之前发送。 要将处理程序连接到信号,有Signal.connect方法。 要将信号附加到特定的sender(在我们的例子中是模型),我们必须给Signal.connect方法提供sender参数,例如,将pre_save信号附加到我们的Post模型(上面定义),如下所示:

pre_save.connect(our_handler, sender=Post)

Django还提供了用于连接信号的 * 装饰器,这使代码更加惯用。 因此,除了定义our_handler并进行连接之外,我们还可以将our_handler的定义修饰为


from django.dispatch import receiver
...

@receiver(pre_save, sender=Post)
def my_handler(sender, **kwargs):
...

现在,让我们完成处理程序以压缩图像。 pre_save信号还将实例参数发送到处理程序函数,该函数对应于要保存的实际实例。 当我们要检查字段是否已更新时,这特别有用,因为我们不想重复压缩图像。 因此我们可以将处理程序功能设为


from django.db.models.signals import pre_save
from django.dispatch import receiver

@receiver(pre_save, sender=Post)
def handle_image_compression(sender, instance, **kwargs):
try:
 post_obj = Post.objects.get(pk=instance.pk)
except Post.DoesNotExist:
 # the object does not exists, so compress the image
 instance.image = compress_image(instance.image)
else:
 # the object exists, so check if the image field is updated
 if post_obj.image != instance.image:
  instance.image = compress_image(instance.image)

现在,我们的最后一项任务是编写compress_image函数,该函数将使用一个ImageField并返回一个ImageField。 PIL的Image.open()方法只能用于文件路径或文件对象。 这是一个有趣的事实,它是ImageField的超类,它镜像了python的File API,因此,我们可以像使用实际文件一样使用它。 使用Image.open的问题已解决,但是Image.save呢? 事实证明Image.save可以将图像写入BytesIO对象。 因此,我们压缩图像的功能将变为


from PIL import Image
from io import BytesIO
from django.core.files import File
def compress_image(image):
im = Image.open(image)
out = BytesIO()
im.save(out, 'JPEG', quality=70)
compressed = File(out, name=image.name)
im.close()
return compressed

总结

以上所述是小编给大家介绍的django在保存图像的同时压缩图像示例代码详解,希望对大家有所帮助!

来源:https://www.mindg.cn/?p=2484&utm_source=tuicool&utm_medium=referral

标签:django,图像,图片
0
投稿

猜你喜欢

  • python实现K近邻回归,采用等权重和不等权重的方法

    2021-12-21 19:29:26
  • python爬虫爬取淘宝商品比价(附淘宝反爬虫机制解决小办法)

    2021-11-14 06:16:40
  • Python卸载模块的方法汇总

    2022-03-14 16:50:21
  • 如何用表单在线建立目录?

    2010-06-16 09:49:00
  • 浏览器用户体验:Firefox初体验 VS The world

    2008-08-02 11:58:00
  • 在Python文件中指定Python解释器的方法

    2023-06-24 13:22:50
  • 优化MySQL数据库查询的三种方法

    2009-03-09 15:19:00
  • arcgis使用Python脚本进行批量截图功能实现

    2021-04-25 03:40:05
  • Python常用工具之音频调整音量

    2023-10-29 03:15:33
  • 利用Python绘制创意中秋节月饼

    2023-02-19 17:52:41
  • Pycharm挂代理后依旧插件下载慢的完美解决方法

    2023-06-17 23:07:31
  • 利用python实现逐步回归

    2023-10-05 19:24:27
  • python判断所输入的任意一个正整数是否为素数的两种方法

    2022-02-26 12:43:14
  • Python Pygame实现可控制的烟花游戏

    2021-09-08 20:29:02
  • 检测你的SQL Server是否有特洛伊木马

    2009-02-05 15:58:00
  • 如何用我的国际域名做虚拟域名?

    2010-06-16 09:53:00
  • 使用python Telnet远程登录执行程序的方法

    2022-12-22 11:56:57
  • React实现表格选取

    2023-08-25 02:56:17
  • [翻译]标记语言和样式手册 Chapter 15 为body指定样式

    2008-02-21 12:36:00
  • 关于递归运算的顺序测试代码

    2023-08-24 13:04:16
  • asp之家 网络编程 m.aspxhome.com