使用Python通过POST请求发送多个PIL Image的StringIO
我在电脑上有一张存储的图片。我用 Python图像模块 打开它。接着,我用这个模块把这张图片裁剪成几块。最后,我想通过一个POST请求把这些图片上传到一个网站上。
因为这些小图片是PIL对象,所以我把它们转换成StringIO,这样就可以在不把它们保存在电脑上的情况下发送表单。
不幸的是,我遇到了一个错误,而如果这些图片是直接保存在我的电脑上,就没有问题。我不明白为什么会这样。
你可以在这里访问这个网站: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()
上,因为同样的循环在保存到磁盘然后上传时也不工作。此外,如果在上传之间加上 time.sleep(1)
,似乎就能正常工作。
任何帮助都非常欢迎,因为我真的卡住了。
1 个回答
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)