将PIL图像对象上传到Amazon s3 python

joh*_*ohn 6 python image amazon-s3

我想从网上获取一张图片并将其上传到亚马逊s3.在这样做的同时,我想检查图像尺寸.我在Python 3中有以下代码:

from PIL import Image
import requests

# Get response
response = requests.get(url, stream= True)

# Open image
im = Image.open(response.raw)

# Get size
size = im.size

# Upload image to s3
S3.Client.upload_fileobj(
    im, # This is what i am trying to upload
    AWS_BUCKET_NAME,
    key,
    ExtraArgs={
        'ACL': 'public-read'
    }
)
Run Code Online (Sandbox Code Playgroud)

问题是PIL图像对象不支持读取.我尝试上传PIL图像对象时收到以下错误im.

ValueError: Fileobj must implement read
Run Code Online (Sandbox Code Playgroud)

它只在我尝试上传'response.raw'时有效,但我需要获取图像尺寸.如何将PIL图像对象更改为类文件对象?是否有更简单的方法来获取尺寸,同时仍然能够将图像上传到s3?

所以问题是; 获取图像尺寸后如何将图像上传到s3?

小智 12

您可以将文件保存到真实文件对象或内存中的对象等文件,而不是调用read()来获取文件内容.然后在上面调用getValue().

下面是一个示例函数,您可以将文件内容传递到其中,打印出高度和宽度,然后以AWS客户端put_object函数将接受的格式返回文件数据作为Body参数.

from PIL import Image
import io

def modify_image(image, format):
    pil_image = Image.open(image)

    # Prints out (1280, 960) 
    print(pil_image.size)

    in_mem_file = io.BytesIO()

    # format here would be something like "JPEG". See below link for more info.
    pil_image.save(in_mem_file, format=format)
    return in_mem_file.getvalue()
Run Code Online (Sandbox Code Playgroud)

这里还有单独的width和height属性:http://pillow.readthedocs.io/en/3.4.x/reference/Image.html#attributes

有关文件格式的更多信息,请访问http://pillow.readthedocs.io/en/3.4.x/handbook/image-file-formats.html

注意:示例使用Python 3.6.1

  • 只是对下一个人的唠叨:`format=format` 应该是 `format=pil_image.format` (5认同)

nbe*_*hat 6

您需要使用类似文件的对象,但不应getValue()以与已接受答案相反的方式进行调用。使用以下代码段,然后可以in_mem_file在调用时使用将该图像上传到S3 upload_fileobj

from PIL import Image
import io

# Open image
pil_image = Image.open(response.raw)

# Save the image to an in-memory file
in_mem_file = io.BytesIO()
pil_image.save(in_mem_file, format=pil_image.format)
in_mem_file.seek(0)

# Upload image to s3
client_s3.upload_fileobj(
    in_mem_file, # This is what i am trying to upload
    AWS_BUCKET_NAME,
    key,
    ExtraArgs={
        'ACL': 'public-read'
    }
)
Run Code Online (Sandbox Code Playgroud)

.seek(0)如果您看到上传的文件为0kB,则需要该部分来倒回文件状对象。