Home > Back-end >  How to send and receive image as part of http form-data using requests and flask
How to send and receive image as part of http form-data using requests and flask

Time:03-29

I would like to make an http POST request, and include an image as part of the multipart/form-data. I'd like to avoid encoding this image as base64, and just send it as a binary blob, which I know that http can handle.

Here is my code on the client side:

from __future__ import print_function
import requests
import json
import cv2


def post_encoded_image(url, headers):
    img = open("cyrus.jpg", 'rb').read()
    payload = {'image': img, 'identity': 'cyrus'}
    r = requests.post(url   "encoded-image", data=payload)
    print(r)

url = "http://localhost:8080/"
content_type = 'multipart/form-data'
headers = {'content-type': content_type}

post_encoded_image(url, headers)

On the server side, my code looks like this:

from flask import Flask, request
import flask
import tfsdk
import numpy as np
from colorama import Fore
from colorama import Style
import os
import cv2

@app.route('/encoded-image', methods=['POST'])
def test():    
    image = request.form.get("image")
    nparr = np.fromstring(image, np.uint8)

    img = cv2.imdecode(nparr, cv2.IMREAD_COLOR)

    print(type(img))

    return "success"


if __name__ == '__main__':
    app.run()


When I make the request, the server prints the type of img as NoneType, meaning the call to imdecode didn't work, meaning something strange is going on the server side with the encoded image.

What is the proper way to do this?

Edit I was able to achieve the desired functionality by doing the following:

client:

from __future__ import print_function
import requests
import json
import cv2


def post_encoded_image(url, headers):
    img = open("cyrus.jpg", 'rb').read()
    file = {'image': img}
    data = {'identity': 'cyrus'}
    r = requests.post(url   "encoded-image", data=data, files=file)
    print(r)

url = "http://localhost:8080/"
content_type = 'multipart/form-data'
headers = {'content-type': content_type}

post_encoded_image(url, headers)


Server:


@app.route('/encoded-image', methods=['POST'])
def test():    
    ID = request.form.get("identity")
    image = request.files['image'].read()
    nparr = np.fromstring(image, np.uint8)

Is this the proper way of doing it?

CodePudding user response:

I was able to achieve the desired functionality as follows:

Client:

from __future__ import print_function
import requests
import json
import cv2


def post_encoded_image(url, headers):
    img = open("cyrus.jpg", 'rb').read()
    file = {'image': img}
    data = {'identity': 'cyrus'}
    r = requests.post(url   "encoded-image", data=data, files=file)
    print(r)

url = "http://localhost:8080/"
content_type = 'multipart/form-data'
headers = {'content-type': content_type}

post_encoded_image(url, headers)

Server:


@app.route('/encoded-image', methods=['POST'])
def test():    
    ID = request.form.get("identity")
    image = request.files['image'].read()
    nparr = np.fromstring(image, np.uint8)
  • Related