django在保存图像的同时压缩图像示例代码详解
假设我们有一个非常简单的Post模型,它将是一个图像及其描述,
fromdjango.dbimportmodels classPost(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会导致图像尺寸大于原本的。
fromPILimportImage im=Image.open('/some/path/to/image') im.save('/desired/path/new_image_name.jpg',quality=70) im.close()
使用quality参数不是减小大小的唯一方法。例如,您可以将其与调整图像大小相结合,以获得更小的图像尺寸。
利用Djangosignals
信号允许某些发送者通知一组接收者已经采取了某些措施。
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的定义修饰为
fromdjango.dispatchimportreceiver ... @receiver(pre_save,sender=Post) defmy_handler(sender,**kwargs): ...
现在,让我们完成处理程序以压缩图像。pre_save信号还将实例参数发送到处理程序函数,该函数对应于要保存的实际实例。当我们要检查字段是否已更新时,这特别有用,因为我们不想重复压缩图像。因此我们可以将处理程序功能设为
fromdjango.db.models.signalsimportpre_save fromdjango.dispatchimportreceiver @receiver(pre_save,sender=Post) defhandle_image_compression(sender,instance,**kwargs): try: post_obj=Post.objects.get(pk=instance.pk) exceptPost.DoesNotExist: #theobjectdoesnotexists,socompresstheimage instance.image=compress_image(instance.image) else: #theobjectexists,socheckiftheimagefieldisupdated ifpost_obj.image!=instance.image: instance.image=compress_image(instance.image)
现在,我们的最后一项任务是编写compress_image函数,该函数将使用一个ImageField并返回一个ImageField。PIL的Image.open()方法只能用于文件路径或文件对象。这是一个有趣的事实,它是ImageField的超类,它镜像了python的FileAPI,因此,我们可以像使用实际文件一样使用它。使用Image.open的问题已解决,但是Image.save呢?事实证明Image.save可以将图像写入BytesIO对象。因此,我们压缩图像的功能将变为
fromPILimportImage fromioimportBytesIO fromdjango.core.filesimportFile defcompress_image(image): im=Image.open(image) out=BytesIO() im.save(out,'JPEG',quality=70) compressed=File(out,name=image.name) im.close() returncompressed
总结
以上所述是小编给大家介绍的django在保存图像的同时压缩图像示例代码详解,希望对大家有所帮助!
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。