PIL无法识别流式传输到io.BytesIO的Google云端硬盘图片的图片文件

时间:2018-02-02 23:22:32

标签: python google-drive-api python-imaging-library stringio bytesio

我正在使用Drive API下载image。在Python中下载文件documentation后,我最终得到一个变量fh,它是一个填充的io.BytesIO实例。我尝试将其保存为图像:

file_id = "0BwyLGoHzn5uIOHVycFZpSEwycnViUjFYQXR5Nnp6QjBrLXJR"
request = service.files().get_media(fileId=file_id)
fh = io.BytesIO()
downloader = MediaIoBaseDownload(fh, request)
done = False
while done is False:
    status, done = downloader.next_chunk()
    print('Download {} {}%.'.format(file['name'],
                                    int(status.progress() * 100)))
    fh.seek(0)
image = Image.open(fh) # error

错误是:cannot identify image file <_io.BytesIO object at 0x106cba890>。实际上,another image不会出现错误,但大多数图像都会出现错误,包括我在本文开头链接的图像。

阅读this answer后,我将最后一行更改为:

byteImg = fh.read()
dataBytesIO = io.BytesIO(byteImg)
image = Image.open(dataBytesIO) # still the same error

我还试过this answer,我将第一个代码块的最后一行更改为

byteImg = fh.read()
image = Image.open(StringIO(byteImg))

但我仍然遇到cannot identify image file <StringIO.StringIO instance at 0x106471e60>错误。

我尝试过使用替代品(requests,urllib)而没有结果。如果我手动下载,我可以Image.open图像。

这个错误在一个月前还没有出现,并且最近突然出现在这个代码所在的应用程序中。我花了几天调试这个错误没有成功,最终把问题带到了Stack Overflow。我正在使用from PIL import Image

1 个答案:

答案 0 :(得分:2)

抛弃云端服务的MediaIOBaseDownload。而是使用媒体文件的webContentLink属性(用于在浏览器中下载文件内容的链接,仅适用于具有二进制内容的文件)。阅读更多here

通过该内容链接,我们可以使用其他形式的流式传输 - requestsshutil库以及 - 来获取图片。

import requests
import shutil

r = requests.get(file['webContentLink'], stream=True)
with open('output_file', 'wb') as f:
    shutil.copyfileobj(r.raw, f)