#python #image #post #python-imaging-library #stringio
#python #изображение #Публикация #python-imaging-library #stringio
Вопрос:
У меня есть сохраненное изображение на моем компьютере. Я открываю его с помощью модуля Python Image. Затем я обрезаю это изображение на несколько частей, используя этот модуль. В заключение я хотел бы загрузить изображение с помощью 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()
, что один и тот же цикл for не работал для сохранения на диск и последующей загрузки. Кроме того, если вы добавите a time.sleep(1)
между загрузками, это, похоже, сработает.
Любая помощь будет приветствоваться, пожалуйста, потому что я действительно застрял.
Комментарии:
1. В первом случае физического файла вы передаете
upload()
открытыйfile
объект изображения, а во второмStringIO
случае вы передаете ему содержимое файла изображения.2. @martineau Что мне делать? И почему второй случай работает для одного или двух изображений, а затем вызывает исключение?
3. Это может сработать, если вы просто передадите ему
StringIO
объект (с именемmy_file
), потому что первые в основном ведут себя как обычныеfile
объекты.4. @martineau К сожалению, я уже пробовал, и это не удалось. Но это хуже всего, потому что даже первые запросы не работают.
5. Возможно, вам нужно перемотать виртуальный файл на a
my_file.seek(0)
, прежде чем передавать егоupload()
.
Ответ №1:
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)