使用Python在POST请求中从PIL Image发送多个StringIO

时间:2014-06-16 16:08:51

标签: python image post python-imaging-library stringio

我的计算机上有一张存储的图片。我使用Python Image module打开它。然后我使用这个模块将这个图像裁剪成几个部分。最后,我想通过网站上的POST请求上传图片。

因为小图像是PIL对象,所以我将每个图像转换为StringIO,以便能够发送表单而无需将其保存在我的PC上。

不幸的是,我遇到了错误,而如果图像实际存储在我的电脑上,则没有问题。我不明白为什么。

您可以在此处访问该网站:http://www.noelshack.com/api.php 这是一个非常基本的API,可返回上传图片的链接。 在我的情况下,问题是在第二张图片的末尾没有返回任何内容(第一张图片没有问题)。


以下是将图像裁剪成100个部分的编程代码。

import requests
import Image
import StringIO
import os

image = Image.open("test.jpg")
width, height = image.size

images = []

for i in range(10):
    for j in range(10):
        crop = image.crop((i * 10, j * 10, (i + 1) * 10, (j + 1) * 10))
        images.append(crop)

上传图片的功能:

def upload(my_file):
    api_url = 'http://www.noelshack.com/api.php'
    r = requests.post(api_url, files={'fichier': my_file})

    if not 'www.noelshack.com' in r.text:
        raise Exception(r.text)

    return r.text

现在我们有两种可能性。第一种是将100张图像中的每一张保存在磁盘上并上传它们。

if not os.path.exists("directory"):
    os.makedirs("directory")

i = 0
for img in images:
    img.save("directory/" + str(i) + ".jpg")
    i += 1

for file in os.listdir("directory"):
    with open("directory/" + file, "rb") as f:
        print upload(f)

它就像一个魅力,但它不是很方便。所以,我想使用StringIO。

for img in images:
    my_file = StringIO.StringIO()
    img.save(my_file, "JPEG")
    print upload(my_file.getvalue())
    # my_file.close() -> Does not change anything

打印第一个链接,但该函数会引发异常。

我认为问题在于img.save(),因为同样类型的for循环无法保存到磁盘然后上传。此外,如果您在上传之间添加time.sleep(1),它似乎可以正常工作。

欢迎任何帮助,因为我真的被卡住了。

1 个答案:

答案 0 :(得分:2)

my_file.getvalue()返回一个字符串。你需要的是一个类文件对象,my_file已经是。像对象这样的文件有一个光标,可以说,它指的是从哪里读取或写入。所以,如果你在上传之前做了my_file.seek(0),它应该得到修复。

将代码修改为:

for img in images:
    my_file = StringIO.StringIO()
    img.save(my_file, "JPEG")
    my_file.seek(0)
    print upload(my_file)