图像缩略图 Django Backblaze B2

我正在使用 Django 和 Backblaze B2 构建一个照片查看和存储网站,我计划上传很多大(文件大小)照片。


我的计划是使用缩略图进行照片浏览,这些需要自动生成。照片上传到 Django,然后 Django 将照片上传到 B2,然后再次下载,创建缩略图并将缩略图上传到 B2。


下载全尺寸图像步骤对我来说似乎没有必要,因为文件已经通过 Django 网络服务器上传了。Django 不能将上传的照片保存在内存(或临时本地存储)中,构建缩略图,然后将全尺寸图像和缩略图上传到 B2 吗?


我正在使用下面的代码save()在Photo模型的步骤中生成缩略图并且它可以工作。我只是在寻找一种方法来提高效率,而无需再次下载全尺寸图像。我想过在PhotoForm使用重写的save()方法中执行此操作,但我无法找到如何执行此操作。我还包含了自定义B2Storage类的代码。


如果有人能给我一个我应该采取的方法,我将不胜感激。谢谢!


模型/照片.py

import os

from io import BytesIO


from PIL import Image

from django.core.files.base import ContentFile

from django.db import models


from fotoplatform.storage import B2Storage


THUMB_SIZE = (400, 400)



class Photo(models.Model):

    title = models.CharField(max_length=50)

    photo = models.ImageField(storage=B2Storage(), unique=True)

    thumbnail = models.ImageField(storage=B2Storage(), unique=True)


    def save(self, *args, **kwargs):

        if not self.thumbnail:

             self.make_thumbnail()

        super(Photo, self).save(*args, **kwargs)


    def make_thumbnail(self):

        try:

            image = Image.open(self.photo)

        except:

            raise Exception('Unable to open photo')


        image.thumbnail(THUMB_SIZE, Image.ANTIALIAS)


        thumb_name, thumb_extension = os.path.splitext(self.photo.name)

        thumb_extension = thumb_extension.lower()


        thumb_filename = thumb_name + '_thumb' + thumb_extension


        if thumb_extension in ['.jpg', '.jpeg']:

            FTYPE = 'JPEG'

        elif thumb_extension == '.gif':

            FTYPE = 'GIF'

        elif thumb_extension == '.png':

            FTYPE = 'PNG'

        else:

            raise Exception("Unknown extension")


        temp_thumb = BytesIO()

        image.save(temp_thumb, FTYPE)

        temp_thumb.seek(0)


        self.thumbnail.save(thumb_filename, ContentFile(temp_thumb.read()), save=True)

        temp_thumb.close()


慕田峪4524236
浏览 186回答 1
1回答

素胚勾勒不出你

与此同时,我为此想出了一个合理的解决方案。我正在创建一个TempPhoto包含照片文件和其他数据的对象,我想用它来存储。我将照片存储在运行 Django 的服务器上的一个temp_photos文件夹中。然后我在TempPhoto创建对象后调用 Celery 任务并向上传浏览器返回成功响应。Celery 任务同时开始在后台运行,这会创建一个真实的Photo对象,并使用make_thumbnail(self)我的问题中描述的方法生成所需的缩略图。然后它将所有需要的东西上传到 B2。使用 Backblaze B2 的有时缓慢的 API,每张照片最多可能需要 1 分钟,但这并不重要,因为它现在在后台异步运行,独立于 Django 网络服务器。在此任务结束时,TempPhoto对象将被删除,并且本地存储的照片temp_photo也将被删除。我正在寻找一种将任务进度传递回最终用户的方法,但这现在不是太重要。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python