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


Posted in Python onFebruary 11, 2020

假设我们有一个非常简单的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在保存图像的同时压缩图像示例代码详解,希望对大家有所帮助!

Python 相关文章推荐
Python实现的数据结构与算法之队列详解
Apr 22 Python
快速解决安装python没有scripts文件夹的问题
Apr 03 Python
python 多线程中子线程和主线程相互通信方法
Nov 09 Python
通过pycharm使用git的步骤(图文详解)
Jun 13 Python
Python 安装第三方库 pip install 安装慢安装不上的解决办法
Jun 18 Python
python如何以表格形式打印输出的方法示例
Jun 21 Python
Django继承自带user表并重写的例子
Nov 18 Python
python实现高斯(Gauss)迭代法的例子
Nov 20 Python
pytorch实现对输入超过三通道的数据进行训练
Jan 15 Python
PyQt使用QPropertyAnimation开发简单动画
Apr 02 Python
keras绘制acc和loss曲线图实例
Jun 15 Python
python用Tkinter做自己的中文代码编辑器
Sep 07 Python
Python中包的用法及安装
Feb 11 #Python
使用Python实现牛顿法求极值
Feb 10 #Python
关于TensorFlow新旧版本函数接口变化详解
Feb 10 #Python
TensorFlow 多元函数的极值实例
Feb 10 #Python
给 TensorFlow 变量进行赋值的方式
Feb 10 #Python
Python 中的pygame安装与配置教程详解
Feb 10 #Python
Tensorflow 定义变量,函数,数值计算等名字的更新方式
Feb 10 #Python
You might like
php for 循环语句使用方法详细说明
2010/05/09 PHP
php模拟asp中的XmlHttpRequest实现http请求的代码
2011/03/24 PHP
php中cookie的使用方法
2014/03/29 PHP
destoon公司主页模板风格的添加方法
2014/06/20 PHP
使用PHP生成二维码的方法汇总
2015/07/22 PHP
Laravel框架集成UEditor编辑器的方法图文与实例详解
2019/04/17 PHP
JQuery中阻止事件冒泡几种方式及其区别介绍
2014/01/15 Javascript
js函数名与form表单元素同名冲突的问题
2014/03/07 Javascript
jquery如何把数组变为字符串传到服务端并处理
2014/04/30 Javascript
JQuery中$(document)是什么意思有什么作用
2014/07/21 Javascript
jquery uploadify 在FF下无效的解决办法
2014/09/26 Javascript
jQuery中DOM树操作之复制元素的方法
2015/01/23 Javascript
JQuery查找DOM节点的方法
2015/06/11 Javascript
js实现文本框支持加减运算的方法
2015/08/19 Javascript
jquery插件uploadify实现带进度条的文件批量上传
2015/12/13 Javascript
jquery设置表单元素为不可用的简单代码
2016/07/04 Javascript
微信小程序 地图定位简单实例
2016/10/14 Javascript
利用Console来Debug的10个高级技巧汇总
2018/03/26 Javascript
微信小程序实现留言板功能
2018/11/02 Javascript
layui实现下拉框三级联动
2019/07/26 Javascript
nodejs制作小爬虫功能示例
2020/02/24 NodeJs
[15:57]教你分分钟做大人:斧王
2014/10/30 DOTA
Python进阶_关于命名空间与作用域(详解)
2017/05/29 Python
利用python解决mysql视图导入导出依赖的问题
2017/12/17 Python
mac安装scrapy并创建项目的实例讲解
2018/06/13 Python
python selenium 获取标签的属性值、内容、状态方法
2018/06/22 Python
在django模板中实现超链接配置
2019/08/21 Python
解决使用python print打印函数返回值多一个None的问题
2020/04/09 Python
给keras层命名,并提取中间层输出值,保存到文档的实例
2020/05/23 Python
解决python3.x安装numpy成功但import出错的问题
2020/11/17 Python
《自然之道》教学反思
2014/02/11 职场文书
公司委托书格式范文
2014/10/09 职场文书
党员群众路线教育实践活动学习笔记
2014/11/05 职场文书
Python实现Telnet自动连接检测密码的示例
2021/04/16 Python
python 模块重载的五种方法
2021/04/24 Python
MySQL数据库10秒内插入百万条数据的实现
2021/11/01 MySQL