为了在上传时调整图像大小(使用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'
这是图像的正确位置。如果我将该地址放在浏览器中,则图像就在那里。我尝试了很多其他的东西,但到目前为止,没有运气。
答案 0 :(得分:9)
你应该尽量避免保存到绝对路径;有一个File Storage API可以为你抽象出这些类型的操作。
查看PIL Documentation,save()
函数似乎支持传递类似文件的对象而不是路径。
我不在我可以测试此代码的环境中,但我相信你需要做这样的事情而不是你的最后一行:
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()