将PIL图像对象上载到Amazon s3 python
我想从网络上获取一张图片并上传到AmazonS3。在执行此操作时,我想检查图像尺寸。 我在Python 3中有以下代码:将PIL图像对象上载到Amazon s3 python,python,image,amazon-s3,Python,Image,Amazon S3,我想从网络上获取一张图片并上传到AmazonS3。在执行此操作时,我想检查图像尺寸。 我在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
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?您应该使用
io.BufferIO
response = requests.get(url, stream= True)
f = io.BytesIO(response.content)
image = Image.open(f)
不是调用read()来取回文件内容,而是将文件“保存”到内存中的真实文件对象或类似文件的对象。然后对其调用getValue()
下面是一个示例函数,您可以将文件内容传递到其中,打印出高度和宽度,然后以AWS客户端put_对象函数将接受为主体参数的格式返回文件数据
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()
此处还有单独的宽度和高度属性:
请在此处查看有关文件格式的更多信息
注意:示例使用Python 3.6.1您需要使用类似文件的对象,但与公认的答案相反,您不应该调用
getValue()
。使用以下代码段,您可以在调用upload\u fileobj
时使用\u mem\u file中的将图像上载到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)
部分倒带类似文件的对象。如果您使用werkzeug.datastructures
中的文件存储
,使用reqparse
解析图像,则无需将图像转换为PIL.image
,您可以在FileStorage
本身上使用seek(0)
另外,不要忘记指定文件的内容类型
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'})
这不会改变任何事情。图像打开良好。当我想将图像上载到s3时出现问题。您是否尝试将f
加载到aws中?用f
代替im
是的,我试过了。首先,response
没有一个名为read
的属性,我假设你的意思是response.raw.read()
。当我尝试这样做时,我上传了一个空文件,因为当它用Image.open()打开时,f
已经被清空了。从响应中尝试content
attr怎么样?它仍然只是上传一个空图片。如果我删除Image.open(f)
part所有部分都可以。只是对下一个家伙唠叨:format=format
应该是format=pil\u Image.format
这是准确的答案。谢谢你提供这个。我在尝试被接受的答案,对自己做错的事情有点不知所措。这真的很有帮助。