我想从网上获取图片并将其上传到亚马逊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'
}
)
问题是PIL图像对象不支持读取。当我尝试上传PIL图像对象im
时出现以下错误。
ValueError: Fileobj must implement read
当我尝试上传'response.raw'时它会起作用,但我需要获取图像尺寸。如何将PIL图像对象更改为类文件对象?是否有更简单的方法来获取尺寸,同时仍然能够将图像上传到s3?
所以问题是;获取图像尺寸后如何将图像上传到s3?
答案 0 :(得分:11)
而不是调用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()
此处还有单独的宽度和高度属性: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
答案 1 :(得分:2)
您需要使用类似文件的对象,但不应调用getValue()
,这与公认的答案相反。使用以下代码段,然后可以在调用in_mem_file
时使用upload_fileobj
将图像上传到S3:
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'
}
)
如果您看到上传的文件为0kB,则需要.seek(0)
部分来倒回文件状对象。
答案 2 :(得分:0)
您应该使用io.BufferIO
response = requests.get(url, stream= True)
f = io.BytesIO(response.content)
image = Image.open(f)
答案 3 :(得分:0)
如果您正在使用FileStorage
中的werkzeug.datastructures
,并使用reqparse
解析了图像,则无需将图像转换为PIL.Image
,则可以在seek(0)
本身上使用FileStorage
。
也不要忘记指定文件的Content-type
。
parser = reqparse.RequestParser()
parser.add_argument('image', help='image cannot be blank', type=FileStorage,
location='files', required=True)
args = parser.parse_args()
image = args['image']
image.seek(0)
s3_client.upload_fileobj(image, self.BUCKET_NAME, filename, ExtraArgs={'ContentType': 'image/jpeg'})