【问题标题】:How to save a thumbnail to default_storage(AWS S3) after converting it in Django views.py?在 Django views.py 中转换缩略图后如何将缩略图保存到 default_storage(AWS S3)?
【发布时间】:2021-02-19 03:46:15
【问题描述】:

我有一个允许上传图片的 HTML 表单。我想将原始图像保存到 S3 存储,然后将其转换为缩略图并将缩略图保存到同一存储中。

我只能保存原始图像,但在尝试保存时使用 PIL 将其转换为缩略图后,我得到“服务器错误 500”

我的观点代码如下,

from django.core.files.storage import default_storage as storage
class upload(View):
def post(self, request):
    image = request.FILES['pic']
    storage.save(image.name, image)
    thisfile = storage.open(image.name)
    newimg = Image.open(thisfile)
    thumb = newimg.resize((128,128), Image.ANTIALIAS)
    storage.save("newimagename", newimg)

    #Trying to save it this way doesn't work either
    #thisobj = userProfile.objects.get(user= request.user)
    #thisobj.image = newimg
    #thisobj.save()

我尝试了一些打印语句,以确保它正在转换文件没有问题,但它保存到内存中并打印出来,

<PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=600x600 at 0x105C1DEF0>

我尝试覆盖 models.py 中的保存方法,但我得到了同样的错误

def save(self, *args, **kwargs):
    super(userProfile, self).save(*args, **kwargs)
    if self.image:
        self.image.name = "y.JPG"
        image = Image.open(self.image.path)
        image = image.resize((128,128), Image.ANTIALIAS)
        image.save(self.image.path)

【问题讨论】:

    标签: python django django-models django-views django-model-field


    【解决方案1】:

    试试这个:

     def save(self, *args, **kwargs):
         super().save(*args, **kwargs)
         img = Image.open(self.image.path)
         if img.height > 128 or img.width > 128:
             output_size = (128, 128)
             img.thumbnail(output_size)
             img.save(self.image.path)
    

    【讨论】:

    【解决方案2】:

    经过大量挖掘,我想出了两种不同的解决方案!

    1- 覆盖models.py中的“Save”方法如下,

    from PIL import Image
    from io import BytesIO
    from django.core.files.uploadedfile import InMemoryUploadedFile
        def save(self, *args, **kwargs):
        super(userProfile, self).save(*args, **kwargs)
        previous = userProfile.objects.get(id = self.id)
        if self.image.width > 128:
            orig = Image.open(self.image)
            orig.thumbnail((128,128), Image.ANTIALIAS)
            fileBytes = BytesIO()
            orig.save(fileBytes, format="JPEG")
            memoryFile = InMemoryUploadedFile(fileBytes, None, str(self.user) + "_thumb.JPG", 'image/jpeg',1, None)
            self.image = memoryFile
            self.image.save(self.image.name, self.image)
    

    2- 使用默认存储保存上传的文件。

    from io import BytesIO
    from django.core.files.storage import default_storage
    from django.core.files.uploadedfile import InMemoryUploadedFile
    class upload(View):
      def post(self, request):
        image = request.FILES['pic']
        #Save the image first to the DB
        default_storage.save(image.name, image)
        #Open the file in the DB
        thisdude = default_storage.open(image.name)
        #Use the opened file in the DB in Images
        img = Image.open(thisdude)
        # Resize that babe
        img.thumbnail((128, 128), Image.ANTIALIAS)
        #Get the Bytes of the file from memory
        thumbnailString = BytesIO()
        #Save the image with the bytes as JPEG
        img.save(thumbnailString, format='JPEG')
        #Get the file in the memory
        thumb_file = InMemoryUploadedFile(thumbnailString, None, 'foo.jpg', 'image/jpeg',1, None)
        #Save it to the DB
        default_storage.save("abc.jpg", thumb_file)
        return redirect("index")
    

    【讨论】:

      【解决方案3】:

      你可以使用一个很好的库来完成你想做的事情。

      https://github.com/codingjoe/django-stdimage

      它会在上传时制作原始文件的缩略图。并且完全兼容 S3。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-11-17
        • 2011-08-18
        • 2021-07-23
        • 1970-01-01
        • 2016-09-11
        • 2017-12-12
        • 1970-01-01
        相关资源
        最近更新 更多