枕头调整Amazon S3上的图像(缩略图) - Django

时间:2017-10-23 13:40:41

标签: python django amazon-s3 pillow

保存时我会尝试调整图像大小。 具体来说,我的图像存储在Amazon S3上,然后我使用django-storagesboto3第三方应用程序

保存图像时,这会存储在我的Amazon S3存储桶中,并具有以下访问URL:

https://s3-sa-east-1.amazonaws.com/ihost-project/media/studyoffer_images/algoritmos-para-ensenanza/15061122523583.jpg

保存图片和调整图片大小的代码如下:

class UploadStudyOffer(models.Model):
    study_offer = models.ForeignKey(StudiesOffert, related_name='uploadsstudyoffer')
    image = models.ImageField(upload_to=get_image_path)
    # images folder per object

    def save(self, *args, **kwargs):
        super(UploadStudyOffer, self).save(*args, **kwargs)
        # We first check to make sure an image exists
        if self.image:
            # Open image and check their size
            image = Image.open(self.image)
            i_width, i_height = image.size
            max_size = (100,100)

            # We resize the image if it's too large
            if i_width > 1000:
                image.thumbnail(max_size, Image.ANTIALIAS)
                image.save(self.image.path)

当我上传图片时,收到此消息:

Exception Type: NotImplementedError at /host/study-offer/algoritmos-para-ensenanza/edit/images/
Exception Value: This backend doesn't support absolute paths.

我不确定,如果错误是在storagesboto后端或Pillow中管理的。 然后在Pillow级别,我在保存图像时找到了以下选项,例如:

我更改了部分代码:

image.save(self.image.path)

为:

image.save(self.image.name)

我收到了这个错误:

File "/home/bgarcial/workspace/hostayni_platform/hosts/models.py" in save
  542.                 image.save(self.image.name) #[Errno 2] No such file or directory: 'studyoffer_images/ingenieria-de-sistemas/15061122523583.jpg'

File "/home/bgarcial/.virtualenvs/hostayni/lib/python3.6/site-packages/PIL/Image.py" in save
  1725.             fp = builtins.open(filename, "w+b")

Exception Type: FileNotFoundError at /host/study-offer/algoritmos-para-ensenanza/edit/images/
Exception Value: [Errno 2] No such file or directory: 'studyoffer_images/algoritmos-para-ensenanza/1900-X-1080-Wallpapers-022.jpg'

当然,我的图像存储在Amazon S3中而不是本地存储在我的项目或硬盘中,然后我使用这种方式的url参数:

我改变了

image.save(self.image.name)

image.save(self.image.url)

我收到了这个错误:

Exception Type: FileNotFoundError at /host/study-offer/algoritmos-para-ensenanza/edit/images/
Exception Value: [Errno 2] No such file or directory: 'https://s3-sa-east-1.amazonaws.com/ihost-project/media/studyoffer_images/algoritmos-para-ensenanza/15061122523583.jpg'

获取亚马逊s3图片网址不起作用,即使网址是有效的网址https://s3-sa-east-1.amazonaws.com/ihost-project/media/studyoffer_images/algoritmos-para-ensenanza/15061122523583.jpg

然后我改变了

image.save(self.image.url)

为:

image.save(self.image.file)

我的图片上传时没有任何错误,但未调整大小并以原始格式上传。

如何处理从我的应用程序上传的图像,其结果在使用后保存在Amazon S3上?

2 个答案:

答案 0 :(得分:2)

这是Django / Python的新手,但这就是我解决的方法。将大文件保存到AWS,使用Pillow打开它,然后调整大小并保存在内存中。然后按照default_storage help docs的建议使用django-storages推送到AWS。请注意,img.thumbnail将保留长宽比,仅将图像的较长边缘设置为1000像素。 image是Django模型ImageField

from django.core.files.storage import default_storage
from io import BytesIO

..

def save(self, *args, **kwargs):
    #run save of parent class above to save original image to disk
    super().save(*args, **kwargs)

    memfile = BytesIO()

    img = Image.open(self.image)
    if img.height > 1000 or img.width > 1000:
        output_size = (1000, 1000)
        img.thumbnail(output_size, Image.ANTIALIAS)
        img.save(memfile, 'JPEG', quality=95)
        default_storage.save(self.image.name, memfile)
        memfile.close()
        img.close()

答案 1 :(得分:1)

您可以更轻松地使用easy_thumbnails app。

如果您想在保存时裁剪图像,则可以使用以下方法裁剪:

from easy_thumbnails.fields import ThumbnailerImageField

CROP_SETTINGS = {'size': (1000, 500), 'crop': 'smart'}

class UploadStudyOffer(models.Model):

    image =ThumbnailerImageField(upload_to=get_image_path,
                                         resize_source=CROP_SETTINGS)

或者您可以在模板中手动指定图像的大小:

{% load thumbnail %}

<img src="{% thumbnail offer.image 1000x500 crop %}" alt="" />