Django - 获取PIL Image保存方法以使用Amazon s3boto Storage

时间:2013-02-04 04:21:07

标签: django amazon-s3 python-imaging-library boto

为了在上传时调整图像大小(使用PIL),我正在覆盖我的文章模型的保存方法,如下所示:

def save(self):
    super(Article, self).save()
    if self.image:
        size = (160, 160)
        image = Image.open(self.image)
        image.thumbnail(size, Image.ANTIALIAS) 
        image.save(self.image.path)

这在本地工作但在生产中我收到错误: NotImplementedError:此后端不支持绝对路径。

我尝试用

替换image.save行
image.save(self.image.url)

然后我得到一个IOError: [Errno 2]没有这样的文件或目录:'https://my_bucket_name.s3.amazonaws.com/article/article_images/2.jpg'

这是图像的正确位置。如果我将该地址放在浏览器中,则图像就在那里。我尝试了很多其他的东西,但到目前为止,没有运气。

2 个答案:

答案 0 :(得分:9)

你应该尽量避免保存到绝对路径;有一个File Storage API可以为你抽象出这些类型的操作。

查看PIL Documentationsave()函数似乎支持传递类似文件的对象而不是路径。

我不在我可以测试此代码的环境中,但我相信你需要做这样的事情而不是你的最后一行:

from django.core.files.storage import default_storage as storage

fh = storage.open(self.image.name, "w")
format = 'png'  # You need to set the correct image format here
image.save(fh, format)
fh.close()

答案 1 :(得分:0)

对我来说 default.storage.write() 不起作用,image.save() 不起作用,这个起作用了。如果有人仍然感兴趣,请查看此代码。我为缩进道歉。我的项目使用的是 Cloudinary 和 Django 小项目。

    from io import BytesIO
    from django.core.files.base import ContentFile
    from django.core.files.storage import default_storage as storage    

    def save(self, *args, **kargs):
    super(User, self).save(*args, **kargs)
    # After save, read the file
    image_read = storage.open(self.profile_image.name, "r")
    image = Image.open(image_read)
        if image.height > 200 or image.width > 200:
           size = 200, 200
        
          # Create a buffer to hold the bytes
           imageBuffer = BytesIO()

          # Resize  
           image.thumbnail(size, Image.ANTIALIAS)

          # Save the image as jpeg to the buffer
           image.save(imageBuffer, image.format)

          # Check whether it is resized
           image.show()

          # Save the modified image
           user = User.objects.get(pk=self.pk)
           user.profile_image.save(self.profile_image.name, ContentFile(imageBuffer.getvalue()))

           image_read = storage.open(user.profile_image.name, "r")
           image = Image.open(image_read)
           image.show()

        image_read.close()