是否可以使用python open函数打开内存中的图像?

时间:2013-05-19 16:00:51

标签: python facebook-graph-api

我正在使用一个python库(poster),它将类似文件的对象作为参数,文档声明:

类文件对象必须支持.read()和.fileno()或两者 .seek()和.tell()。

我已经使用python open函数尝试了该库,它工作正常。我目前正在使用以下内容从URL下载图像:

access_token = "XXXXXXXXXXXXXXXXXXXXX"
postPhotoUrl = "https://graph.facebook.com/me/photos?access_token=%s" % access_token

register_openers()

# get image from external URL
data = urllib2.urlopen("http://example.com/image.png")
data = StringIO(data.read())

### data, headers = multipart_encode({"source":open("file.png")}) <- WORKS FINE
data, headers = multipart_encode({"source":data})
request = urllib2.Request(postPhotoUrl,data,headers)

编辑:我的目标是从外部URL获取图像并使用facebook图形api进行POST。当我使用python open函数时,我没有任何问题。当我尝试使用StringIO时,没有发送带有POST请求的正文。

1 个答案:

答案 0 :(得分:4)

如果想要使用poster包进行流式HTTP上传,则不应将图像数据转换为PIL Image对象。只是做...

data = urllib2.urlopen("http://example.com/image.png")
data = StringIO(data.read())

...然后您可以将data变量传递给poster

当然,除非你想先用PIL转换图像,但你可能应该在你的问题中提到它。

<强>更新

至于为什么它失败了StringIO,可能是poster正在检查打开文件的文件名,并使用它来确定正确的Content-Type或某些,从StringIO阅读时无法做到。

我从来没有使用过该软件包,并且示例不是很全面,但是当你调用类似的东西时,可能需要检查headers变量之间的区别......

from poster.encode import multipart_encode

data = open('example.png', 'rb')
datagen, headers = multipart_encode({"image1": data})

...与...

from poster.encode import multipart_encode

data = urllib2.urlopen("http://example.com/image.png")
data = StringIO(data.read())
datagen, headers = multipart_encode({"image1": data})

更新#2

看起来我对Content-Type的事情是正确的。来自poster源代码encode.py第168-174行......

        if hasattr(value, 'read'):
            # Looks like a file object
            filename = getattr(value, 'name', None)
            if filename is not None:
                filetype = mimetypes.guess_type(filename)[0]
            else:
                filetype = None

...如果filenameNone,则可能存在其他问题。试试这个......

from poster.encode import multipart_encode, MultipartParam

data = urllib2.urlopen("http://example.com/image.png")
data = StringIO(data.read())
param = MultipartParam(name='source',
                       filename='image.png',
                       filetype='image/png',
                       fileobj=data)
datagen, headers = multipart_encode({"source": param})