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将每个单词按空格分开并保存到文件中
Mar 19 Python
使用Scrapy爬取动态数据
Oct 21 Python
在win10和linux上分别安装Python虚拟环境的方法步骤
May 09 Python
react+django清除浏览器缓存的几种方法小结
Jul 17 Python
python中append实例用法总结
Jul 30 Python
Python 3 判断2个字典相同
Aug 06 Python
Python数据可视化:箱线图多种库画法
Nov 06 Python
keras训练曲线,混淆矩阵,CNN层输出可视化实例
Jun 15 Python
Python虚拟环境库virtualenvwrapper安装及使用
Jun 17 Python
如何利用python进行时间序列分析
Aug 04 Python
推荐值得学习的12款python-web开发框架
Aug 10 Python
Python 在 VSCode 中使用 IPython Kernel 的方法详解
Sep 05 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 select,radio和checkbox默认选择的实现方法
2010/05/15 PHP
php中使用preg_match_all匹配文章中的图片
2013/02/06 PHP
PHP数学运算函数大汇总(经典值得收藏)
2016/04/01 PHP
php注册系统和使用Xajax即时验证用户名是否被占用
2017/08/31 PHP
extjs 为某个事件设置拦截器
2010/01/15 Javascript
jquery动态加载图片数据练习代码
2011/08/04 Javascript
js处理json以及字符串的比较等常用操作
2013/09/08 Javascript
IE中的File域无法清空使用jQuery重设File域
2014/04/24 Javascript
JavaScript实现重置表单(reset)的方法
2015/04/02 Javascript
学习JavaScript设计模式(接口)
2015/11/26 Javascript
基于BootStrap Metronic开发框架经验小结【七】数据的导入、导出及附件的查看处理
2016/05/12 Javascript
基于JavaScript实现鼠标箭头移动图片跟着移动
2016/08/30 Javascript
jQuery实现表格文本框淡入更改值后淡出效果
2016/09/27 Javascript
详解JavaScript中js对象与JSON格式字符串的相互转换
2017/02/14 Javascript
jQuery简单实现遍历单选框的方法
2017/03/06 Javascript
vue2.0结合Element实现select动态控制input禁用实例
2017/05/12 Javascript
jQuery+HTML5实现WebGL高性能烟花绽放动画效果【附demo源码下载】
2017/08/18 jQuery
Jquery的autocomplete插件用法及参数讲解
2019/03/12 jQuery
JS实现倒序输出的几种常用方法示例
2019/04/13 Javascript
Vue实现简单计算器案例
2020/02/25 Javascript
vue实现员工信息录入功能
2020/06/11 Javascript
JavaScript事件委托实现原理及优点进行
2020/08/29 Javascript
Python探索之创建二叉树
2017/10/25 Python
python解析多层json操作示例
2019/12/30 Python
基于python实现MQTT发布订阅过程原理解析
2020/07/27 Python
python 解决selenium 中的 .clear()方法失效问题
2020/09/01 Python
联想瑞士官方网站:Lenovo Switzerland
2017/11/19 全球购物
汉语专业应届生求职信
2013/10/01 职场文书
护士毕业自我鉴定
2014/02/07 职场文书
保密承诺书范文
2014/03/27 职场文书
民事诉讼授权委托书范文
2014/08/02 职场文书
乡镇保密工作承诺书
2015/05/04 职场文书
高一军训口号
2015/12/25 职场文书
适合青年人白手起家的创业项目分享
2019/08/16 职场文书
OpenCV 图像梯度的实现方法
2021/07/25 Python
科普 | 业余无线电知识-波段篇
2022/02/18 无线电