您好,登錄后才能下訂單哦!
使用django怎么實(shí)現(xiàn)在保存圖像的同時(shí)壓縮圖像?針對(duì)這個(gè)問題,這篇文章詳細(xì)介紹了相對(duì)應(yīng)的分析和解答,希望可以幫助更多想解決這個(gè)問題的小伙伴找到更簡(jiǎn)單易行的方法。
假設(shè)我們有一個(gè)非常簡(jiǎn)單的Post模型,它將是一個(gè)圖像及其描述,
from django.db import models class Post(models.Model): text = models.TextField() image = models.ImageField(upload_to='images/')
但是我們要優(yōu)化圖像大小,這將由我們Post的image字段指出。 這樣做有充分的理由-它有助于更快地加載網(wǎng)站/應(yīng)用程序并減少我們的服務(wù)器存儲(chǔ)。 在使用Django之前,首先讓我們簡(jiǎn)單介紹一下使用Pillow進(jìn)行圖像壓縮的概述。
使用Pillow壓縮圖像
Pillow是用于圖像相關(guān)操作的出色Python軟件包。 Image類帶有用于圖像io和操作的方法。 Image.open從文件路徑或文件對(duì)象讀取圖像。 Image類的save方法將質(zhì)量作為以jpg格式保存圖像的可選參數(shù),范圍為1到95,此參數(shù)的默認(rèn)值為75,并且設(shè)置質(zhì)量大于95會(huì)導(dǎo)致圖像尺寸大于 原本的。
from PIL import Image im = Image.open('/some/path/to/image') im.save('/desired/path/new_image_name.jpg', quality=70) im.close()
使用quality參數(shù)不是減小大小的唯一方法。 例如,您可以將其與調(diào)整圖像大小相結(jié)合,以獲得更小的圖像尺寸。
利用Django signals
信號(hào)允許某些發(fā)送者通知一組接收者已經(jīng)采取了某些措施。
Django帶有許多內(nèi)置信號(hào),目前,我們對(duì)django.db.models.signals.pre_save信號(hào)感興趣,該信號(hào)將在調(diào)用模型的save()方法之前發(fā)送。 要將處理程序連接到信號(hào),有Signal.connect方法。 要將信號(hào)附加到特定的sender(在我們的例子中是模型),我們必須給Signal.connect方法提供sender參數(shù),例如,將pre_save信號(hào)附加到我們的Post模型(上面定義),如下所示:
pre_save.connect(our_handler, sender=Post)
Django還提供了用于連接信號(hào)的接收器裝飾器,這使代碼更加慣用。 因此,除了定義our_handler并進(jìn)行連接之外,我們還可以將our_handler的定義修飾為
from django.dispatch import receiver ... @receiver(pre_save, sender=Post) def my_handler(sender, **kwargs): ...
現(xiàn)在,讓我們完成處理程序以壓縮圖像。 pre_save信號(hào)還將實(shí)例參數(shù)發(fā)送到處理程序函數(shù),該函數(shù)對(duì)應(yīng)于要保存的實(shí)際實(shí)例。 當(dāng)我們要檢查字段是否已更新時(shí),這特別有用,因?yàn)槲覀儾幌胫貜?fù)壓縮圖像。 因此我們可以將處理程序功能設(shè)為
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)
現(xiàn)在,我們的最后一項(xiàng)任務(wù)是編寫compress_image函數(shù),該函數(shù)將使用一個(gè)ImageField并返回一個(gè)ImageField。 PIL的Image.open()方法只能用于文件路徑或文件對(duì)象。 這是一個(gè)有趣的事實(shí),它是ImageField的超類,它鏡像了python的File API,因此,我們可以像使用實(shí)際文件一樣使用它。 使用Image.open的問題已解決,但是Image.save呢? 事實(shí)證明Image.save可以將圖像寫入BytesIO對(duì)象。 因此,我們壓縮圖像的功能將變?yōu)?/p>
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
關(guān)于使用django怎么實(shí)現(xiàn)在保存圖像的同時(shí)壓縮圖像問題的解答就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關(guān)注億速云行業(yè)資訊頻道了解更多相關(guān)知識(shí)。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。