使用Boto将枕头文件保存到S3

Run*_*oop 2 django amazon-s3 pillow

我通过s3boto将Amazon S3用作存储后端。我有一个带有ImageField的Image模型。通过管理员上传图像后,该图像将成功上传到S3。我现在想做的是使用Pillow创建缩略图后保存。我已经通过在其上调用show()方法验证了缩略图已创建,但是由于某种原因它没有被上传到S3。我认为我的保存方式可能​​是错误的-任何建议请多加赞赏。

task.py

from celery import shared_task
from .models import Image
import os
from django.core.files.storage import default_storage as storage
from PIL import Image as PillowImage

@shared_task
def create_thumbnails(pk):
    try:
        image = Image.objects.get(pk=pk)
    except Image.ObjectDoesNotExist:
        pass
    thumbnail_size = (450,200)
    filename, ext = os.path.splitext(image.image.name)
    try:
        fh = storage.open(image.image.name, 'r')
        im = PillowImage.open(fh)
        im.thumbnail(thumbnail_size)
        im.show() # TEST - This opens the resized image in Preview on my mac
        filename = filename +'_thumbnail' +ext
        new_file = storage.open(filename, 'w')
        im.save(new_file, "PNG")
        new_file.close()
    except IOError as error:
        print("cannot create thumbnail for ", filename, 'error ', error)
Run Code Online (Sandbox Code Playgroud)

Django 1.85

python 2.7.10

Jer*_* S. 7

这非常有用,我用它来找到一种无需直接使用boto就可以将图像从django写入s3的方法。

基本上,PIL的save()方法不适用于s3,但default_storage.write()方法适用。关键是使用default_storage.write()方法直接从StringIO内存文件中写入二进制数据,如下所示:

file_to_write.write(memory_file.getvalue())
Run Code Online (Sandbox Code Playgroud)

这是我在django shell(python manage.py shell)中运行的代码,以对此进行测试:

>>> from django.core.files.storage import default_storage as storage
>>> from PIL import Image
>>> import StringIO
>>> i = storage.open('ImageToCreate.jpg','w+')
>>> m = storage.open('ImageAlreadyOnS3.jpg','r')
>>> im = Image.open(m)
>>> im = im.resize((640,360),3)
>>> sfile = StringIO.StringIO() #cStringIO works too
>>> im.save(sfile, format="JPEG")
>>> i.write(sfile.getvalue())
>>> i.close()
>>> m.close()
Run Code Online (Sandbox Code Playgroud)

它也可以在我的views.py中使用。

我发现它很有用,因为它可以在远程s3存储和本地开发环境(笔记本电脑上的文件夹)上工作。