Как сохранить эскиз в default_storage (AWS S3) после преобразования его в Django views.py? - PullRequest
0 голосов
/ 24 февраля 2019

У меня есть 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)

Ответы [ 2 ]

0 голосов
/ 25 февраля 2019

После долгих раскопок я нашел 2 разных решения!

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")
0 голосов
/ 25 февраля 2019

Попробуйте это:

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