簡體   English   中英

在 Django views.py 中轉換縮略圖后如何將縮略圖保存到 default_storage(AWS S3)?

[英]How to save a thumbnail to default_storage(AWS S3) after converting it in Django views.py?

我有一個允許上傳圖片的 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中的save方法,但我得到了同樣的錯誤

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)

嘗試這個:

 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)

經過大量挖掘,我想出了兩種不同的解決方案!

1-覆蓋models.py中的“保存”方法如下,

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")

您可以使用一個很好的庫來完成您想做的事情。

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

它在上傳時制作原始文件的縮略圖。 此外,它與 S3 完全兼容。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM