title: How to post an image as a request with Flask Server API in Dart/Flutter?
body: <p>I want to post a request to a Python-based API that has an image in its body. I have tried to send data with 5 methods:</p>
  
  <ol>
  <li>await http.post()</li>
  </ol>
  
  <pre><code>   final api = Uri.parse("https://e8f628d7.ngrok.io/detections");
     Map&lt;String, dynamic&gt; body = {'images': image};
      final response = await http.post(
        api,
        body: body,
      );
  
      if (response.statusCode == 200) {
        final responseJson = json.decode(response.body);
        print(responseJson);
      }
  </code></pre>
  
  <ol start="2">
  <li>Client().post()</li>
  </ol>
  
  <pre><code>     Map&lt;String, dynamic&gt; body = {'images': image};
       var client = new http.Client();
         client.post("https://e8f628d7.ngrok.io/detections",body: body).then((response) {
           print("Post " + response.statusCode.toString());
         });
  </code></pre>
  
  <ol start="3">
  <li>dio</li>
  <li>MultipartRequest </li>
  </ol>
  
  <pre><code>    final api = Uri.parse("https://e8f628d7.ngrok.io/detections");
      var stream = new http.ByteStream(DelegatingStream.typed(image.openRead()));
      var length = await image.length();
      var request = new http.MultipartRequest("POST", api);
      var multipartFileSign = new http.MultipartFile(
          'profile_pic', stream, length,
          filename: path.basename(image.path));
      request.files.add(multipartFileSign);
      // send
      var response = await request.send();
      print(response.statusCode);
      response.stream.transform(utf8.decoder).listen((value) {
        print(value);
      });
  </code></pre>
  
  <ol start="5">
  <li>Link of [DELETED]First Answer to this question:</li>
  </ol>
  
  <pre><code>    if (image == null) return;
      String base64Image = base64Encode(image.readAsBytesSync());
      http.post(api, body: {
        'images': base64Image,
      }).then((res) {
        print(res.statusCode);
        print(json.decode(res.body));
      }).catchError((err) {
        print(err);
      });
    }
  </code></pre>
  
  <p>I am able to send the image and am getting a 200 success response. But, I am not sure if the image is getting altered or any problem happens while sending the image as the response is empty whereas it should have some sort of response.
  This is my app.py from with which my server works:</p>
  
  <pre><code>import time
  from absl import app, logging
  import cv2
  import numpy as np
  import tensorflow as tf
  from yolov3_tf2.models import (
      YoloV3, YoloV3Tiny
  )
  from yolov3_tf2.dataset import transform_images, load_tfrecord_dataset
  from yolov3_tf2.utils import draw_outputs
  from flask import Flask, request, Response, jsonify, send_from_directory, abort
  import os
  
  # customize your API through the following parameters
  classes_path = './data/labels/coco.names'
  weights_path = './weights/yolov3.tf'
  tiny = False                    # set to True if using a Yolov3 Tiny model
  size = 416                      # size images are resized to for model
  output_path = './detections/'   # path to output folder where images with detections are saved
  num_classes = 80                # number of classes in model
  
  # load in weights and classes
  physical_devices = tf.config.experimental.list_physical_devices('GPU')
  if len(physical_devices) &gt; 0:
      tf.config.experimental.set_memory_growth(physical_devices[0], True)
  
  if tiny:
      yolo = YoloV3Tiny(classes=num_classes)
  else:
      yolo = YoloV3(classes=num_classes)
  
  yolo.load_weights(weights_path).expect_partial()
  print('weights loaded')
  
  class_names = [c.strip() for c in open(classes_path).readlines()]
  print('classes loaded')
  
  # Initialize Flask application
  app = Flask(__name__)
  
  # API that returns JSON with classes found in images
  @app.route('/detections', methods=['POST'])
  def get_detections():
      raw_images = []
      images = request.files.getlist("images")
      image_names = []
      for image in images:
          image_name = image.filename
          image_names.append(image_name)
          image.save(os.path.join(os.getcwd(), image_name))
          img_raw = tf.image.decode_image(
              open(image_name, 'rb').read(), channels=3)
          raw_images.append(img_raw)
  
      num = 0
  
      # create list for final response
      response = []
  
      for j in range(len(raw_images)):
          # create list of responses for current image
          responses = []
          raw_img = raw_images[j]
          num+=1
          img = tf.expand_dims(raw_img, 0)
          img = transform_images(img, size)
  
          t1 = time.time()
          boxes, scores, classes, nums = yolo(img)
          t2 = time.time()
          print('time: {}'.format(t2 - t1))
  
          print('detections:')
          for i in range(nums[0]):
              print('\t{}, {}, {}'.format(class_names[int(classes[0][i])],
                                              np.array(scores[0][i]),
                                              np.array(boxes[0][i])))
              responses.append({
                  "class": class_names[int(classes[0][i])],
                  "confidence": float("{0:.2f}".format(np.array(scores[0][i])*100))
              })
          response.append({
              "image": image_names[j],
              "detections": responses
          })
          img = cv2.cvtColor(raw_img.numpy(), cv2.COLOR_RGB2BGR)
          img = draw_outputs(img, (boxes, scores, classes, nums), class_names)
          cv2.imwrite(output_path + 'detection' + str(num) + '.jpg', img)
          print('output saved to: {}'.format(output_path + 'detection' + str(num) + '.jpg'))
  
      #remove temporary images
      for name in image_names:
          os.remove(name)
      try:
          return jsonify({"response":response}), 200
      except FileNotFoundError:
          abort(404)
  
  # API that returns image with detections on it
  @app.route('/image', methods= ['POST'])
  def get_image():
      image = request.files["images"]
      image_name = image.filename
      image.save(os.path.join(os.getcwd(), image_name))
      img_raw = tf.image.decode_image(
          open(image_name, 'rb').read(), channels=3)
      img = tf.expand_dims(img_raw, 0)
      img = transform_images(img, size)
  
      t1 = time.time()
      boxes, scores, classes, nums = yolo(img)
      t2 = time.time()
      print('time: {}'.format(t2 - t1))
  
      print('detections:')
      for i in range(nums[0]):
          print('\t{}, {}, {}'.format(class_names[int(classes[0][i])],
                                          np.array(scores[0][i]),
                                          np.array(boxes[0][i])))
      img = cv2.cvtColor(img_raw.numpy(), cv2.COLOR_RGB2BGR)
      img = draw_outputs(img, (boxes, scores, classes, nums), class_names)
      cv2.imwrite(output_path + 'detection.jpg', img)
      print('output saved to: {}'.format(output_path + 'detection.jpg'))
  
      # prepare image for response
      _, img_encoded = cv2.imencode('.png', img)
      response = img_encoded.tostring()
  
      #remove temporary image
      os.remove(image_name)
  
      try:
          return Response(response=response, status=200, mimetype='image/png')
      except FileNotFoundError:
          abort(404)
  if __name__ == '__main__':
      app.run(debug=True, host = '0.0.0.0', port=5000)
  </code></pre>
  
  <p>I try to send the same image directly through Postman and get the desired response but when I do it with the flutter app, I don't get it. Is there any possibility of the image getting altered or modified? And, is there any other method in which I can send the image to the API other than the above 3?</p>