Search code examples
postdartflutterform-data

How to send an image to an api in dart/flutter?


I saw other questions, but thats not what i want, i dont want to upload an image to a server, i dont want to convert to base64...

I only want to post a file in a form data or something else and get the returned info.

i have this, but has not work:

  void onTakePictureButtonPressed() {
    takePicture().then((String filePath) {
      if (mounted) {
        setState(() {
          imagePath = filePath;
          videoController?.dispose();
          videoController = null;
        });

        http.post('http://ip:8082/composer/predict', headers: {
          "Content-type": "multipart/form-data",
        }, body: {
          "image": filePath,
        }).then((response) {
          print("Response status: ${response.statusCode}");
          print("Response body: ${response.body}");
        });


        if (filePath != null) showInSnackBar('Picture saved to $filePath');
      }
    });
  }

Solution

  • The simplest method would be to post a multipart request like in this post and then post it to the server.

    Make sure to import these in the beginning of the file:

    import 'package:path/path.dart';
    import 'package:async/async.dart';
    import 'dart:io';
    import 'package:http/http.dart' as http;
    import 'dart:convert';
    

    Add this class somewhere in your code:

    upload(File imageFile) async {    
          // open a bytestream
          var stream = new http.ByteStream(DelegatingStream.typed(imageFile.openRead()));
          // get file length
          var length = await imageFile.length();
    
          // string to uri
          var uri = Uri.parse("http://ip:8082/composer/predict");
    
          // create multipart request
          var request = new http.MultipartRequest("POST", uri);
    
          // multipart that takes file
          var multipartFile = new http.MultipartFile('file', stream, length,
              filename: basename(imageFile.path));
    
          // add file to multipart
          request.files.add(multipartFile);
    
          // send
          var response = await request.send();
          print(response.statusCode);
    
          // listen for response
          response.stream.transform(utf8.decoder).listen((value) {
            print(value);
          });
        }
    

    Then upload using:

    upload(File(filePath));
    

    In your code:

    void onTakePictureButtonPressed() {
        takePicture().then((String filePath) {
          if (mounted) {
            setState(() {
              imagePath = filePath;
              videoController?.dispose();
              videoController = null;
            });
    
           // initiate file upload
           Upload(File(filePath));
    
            if (filePath != null) showInSnackBar('Picture saved to $filePath');
          }
        });
      }