skip to Main Content

Here i have my flask function that returns the image:

@app.route("/getResults", methods=['GET'])
def get_results():
    print(request)
    job_key = request.args["id"]
    filename = '/home/pat/projets/giftmaker/webapp/public/workingDir/1/test.png'
    return send_file(filename, mimetype='image/png')

then I have my attemp to read it:

export function Download ({jobID}) {
    
    const [img, setImg] = useState(null);
    
    
    function test() {
        const params = new URLSearchParams([['id', jobID]]);
        axios.get('/getResults', {params}, {responseType: "arraybuffer"})
            .then((response) => {
                setImg(Buffer.from(response.data, "binary").toString("base64"))
            })
            .catch((e) => {
                console.log(e)
            })
     };



    return(
     <div>
        <button onClick={test}> Display </button>
        <img src={`data:image/png;base64,${img}`} />
     </div>
    )
};

this is the response i get from the get request :

�PNG

�
���
IHDR���h���h�����������=�zTXtRaw profile type exif��xڥ�Y��6�m��Vd�H

its actually longer than that but you get the idea…

I have tried so many thing that i found from stackoverflow but nothing seems to work.
I am testing out with a small image but it should be a gif that can be 1-5Mb

The data send from flask.send_file is binary right ?

2

Answers


  1. Chosen as BEST ANSWER

    I am lucky enough to control the back-end so i modified it a little bit

    with open(filepath, "rb") as f:
            encodedZip = base64.b64encode(f.read())
        
        return encodedZip.decode()
    

    frontend:

    function getResults() {       
            //console.log("ok")
            const params = new URLSearchParams([['id', jobID]]);
            axios.get('/getResults', {params}, {responseType: "arraybuffer"})
                .then((response) => {
                  setImg(response.data)
                })
                .catch((e) => {
                    console.log(e)
                })
         };
    
    
    return(
            <div>
                <img src={`data:image/png;charset=utf-8;base64,${img}`} />
            </div>
            
        )
    };
    

  2. Yes, the data returned from send_file is binary. There are multiple reasons why this could go wrong:

    • CORS: Maybe the connection from your frontend was refused, check in the dev tools, if the request was successfull, you should see the image in "Preview"
    • Missing dependecies: You use "Buffer" which is a package you need to import. If that should be the problem, you’d get a error in the console saying that "Buffer is not defined"
    • Also be sure to check that the image you’re returning actually exists 🙂

    I got it working like this:

    api.py

    from flask import Flask, request, send_file
    from flask_cors import CORS
    
    app = Flask(__name__)
    CORS(app)
    
    @app.route("/", methods=['GET'])
    def get_results():
        print(request)
        filename = 'test.png'
        return send_file(filename, mimetype='image/png')
    
    app.run(host='0.0.0.0', port=8081)
    

    App.js

    import React, { useState } from 'react';
    import axios from 'axios';
    import { Buffer } from 'buffer';
    
    function App() {
      const [img, setImg] = useState(null);
    
      function test() {
        axios.get('http://localhost:8081', { responseType: "arraybuffer" })
          .then((response) => {
            setImg(Buffer.from(response.data, "binary").toString("base64"))
          })
          .catch((e) => {
            console.log(e)
          })
      };
    
    
      return (
        <div>
          <button onClick={test}> Display </button>
          <img src={`data:image/png;base64,${img}`} />
        </div>
      )
    }
    
    export default App;
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search