-1

Sending image to the flask server and do object detection on that and send back that image as a response and no of object detected variable value. Flask route function is as below

@app.route('/upload', methods=['POST'])
def upload_file():
    file = request.files['image']
    im = Image.open(file)


    total_count = 0
    for i in keypoints:
        total_count = total_count + 1
    im_with_keypoints = cv2.drawKeypoints(im, keypoints, np.array([]), (0, 0, 255), cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
    file_object = io.BytesIO()
    img = Image.fromarray(im_with_keypoints.astype('uint8'))

    # write PNG in file-object
    img.save(file_object, 'JPEG')

    # move to beginning of file so `send_file()` it will read from start    
    file_object.seek(0)

    return send_file(file_object, mimetype='image/jpeg')

when I do post a request by uploading an image I get the processed image back on POSTMAN but I need to get the value of variable total_count along with the image. I tried calling like this

return '{} {}'.format(total_count,send_file(file_object, mimetype='image/jpeg'))

but I got output as 11 <Response streamed [200 OK]> where the image is stored as object form, is there a way to get the image along with the total_count value as a response? Any suggestion or example on the way of getting both response which is Image and variable total_count?

Nikhil R
  • 95
  • 4
  • 13

2 Answers2

0

Off the top of my head, there are a couple of things you could do, below are pseudocoded-ish versions:

  • Make a custom header in the response and grab it from the headers with whatever is calling this endpoint
from flask import make_response, send_file    

...

response = make_response(send_file(file_object, mimetype='image/jpeg'))
response.headers['Total-Count'] = total_count #might have to make it a string
return response

or

  • Send the file with the total_count as part of the filename and parse it out from whatever is calling this endpoint
from flask import send_file

...

file_name = f"{total_count}_image.jpeg"
return send_file(file_object, mimetype="image/jpeg", as_attachment=True, attachment_filename=file_name)
mclslee
  • 458
  • 1
  • 5
  • 15
0

mclslee's suggestions are quite creative/clever but they feel a bit hacky to me. Here are my ideas:

Base64-encoded image

Code stolen from https://stackoverflow.com/a/31826470/220652

from flask import jsonify
import base64
# other imports

# ...

base64_image = base64.b64encode(file_object.getvalue())
return jsonify(image=base64_image, total_count=total_count)

And it doesn't need to be JSON:

return f"{total_count} {base64_image}"

You haven't said anything about the client, it'd obviously need to know how to decode base64 data but most platforms including JS in the browser can do that.

Image with EXIF tag

Idea stolen from https://stackoverflow.com/a/10834464/220652

Requirement: https://pypi.org/project/exif/

import json
from exif import Image as ExifImage
# other imports

# ...

exif_image = ExifImage(file_object)
# Either ... or ... (no idea whether either works)
exif_image.maker_note = json.dumps(dict(total_count=total_count))
exif_image.user_comment = json.dumps(dict(total_count=total_count))
return send_file(io.BytesIO(exif_image.get_file()), mimetype='image/jpeg')

Here as well the client needs to know how to read EXIF tags from images and again most platforms including JS in the browser can do that.

dAnjou
  • 3,823
  • 7
  • 27
  • 34