54

I would like to upload a image, I am using http.Client() for making requests,

static uploadImage(String id, File file) { var httpClient = createHttpClient(); Map<String, String> headers = new Map<String, String>(); headers.putIfAbsent("Authorization", () => "---"); headers.putIfAbsent("Content-Type", () => "application/json"); var body=new List(); body.add(id.) httpClient.post(URL_UPLOADIMAGE,headers: headers,body: ,encoding: ) } 

What should be the body and encoding part for the request ?

4
  • 1
    You should be able to use the same method from dart question! Commented Jun 30, 2017 at 9:14
  • that did it, however that answer is from older version of library. Commented Jun 30, 2017 at 11:12
  • 3
    request.files.add( new http.MultipartFile.fromBytes("file", file.readAsBytesSync(), filename: "Photo.jpg", contentType: new MediaType("image", "jpg"))); //this works now. Commented Jun 30, 2017 at 11:13
  • having same issue, will you share your solution? Commented Jun 1, 2018 at 2:37

16 Answers 16

68

Use MultipartRequest class

Upload(File imageFile) async { var stream = new http.ByteStream(DelegatingStream.typed(imageFile.openRead())); var length = await imageFile.length(); var uri = Uri.parse(uploadURL); var request = new http.MultipartRequest("POST", uri); var multipartFile = new http.MultipartFile('file', stream, length, filename: basename(imageFile.path)); //contentType: new MediaType('image', 'png')); request.files.add(multipartFile); var response = await request.send(); print(response.statusCode); response.stream.transform(utf8.decoder).listen((value) { print(value); }); } 

name spaces:

import 'package:path/path.dart'; import 'package:async/async.dart'; import 'dart:io'; import 'package:http/http.dart' as http; 
Sign up to request clarification or add additional context in comments.

10 Comments

My uploaded file is always application/octet-stream. Is there a way to get the right content type from the file and how can I set it in the request?
where do I import the MediaType class from
I figured I just had to import 'package:http_parser/http_parser.dart';
DelegatingStream.typed is deprecated.
USE var stream = new http.ByteStream(_image.openRead()); stream.cast(); INSTEAD of DelegatingStream.typed
|
31

The easiest way is to use the http library,

import 'dart:io'; import 'package:http/http.dart' as http; _asyncFileUpload(String text, File file) async{ //create multipart request for POST or PATCH method var request = http.MultipartRequest("POST", Uri.parse("<url>")); //add text fields request.fields["text_field"] = text; //create multipart using filepath, string or bytes var pic = await http.MultipartFile.fromPath("file_field", file.path); //add multipart to request request.files.add(pic); var response = await request.send(); //Get the response from the server var responseData = await response.stream.toBytes(); var responseString = String.fromCharCodes(responseData); print(responseString); } 

5 Comments

Hello , its giving me Unhandled Exception: SocketException: OS Error: Broken pipe, errno = 32 , please suggest
Please check the URL. Make sure you're able to post your file data from Postman
How do I receive it in my .php?
I am not much good at PHP but you can get files using $_FILES["file_field"]
@Santiago if am too late to answer you then it can help some one else. On the server side in my case i accepted it as a normal file from the HTML form and everything went well.
12

Checkout the body in submitForm() method.

File _image; Future cameraImage() async { var image = await ImagePicker.pickImage( source: ImageSource.camera, maxHeight: 240.0, maxWidth: 240.0, ); setState(() { _image = image; }); } submitForm() async { final response = await http.post( uri, headers: { AuthUtils.AUTH_HEADER: _authToken }, body: { 'user_id': userId 'photo': _image != null ? 'data:image/png;base64,' + base64Encode(_image.readAsBytesSync()) : '', }, ); final responseJson = json.decode(response.body); print(responseJson); } 

3 Comments

How do I receive it in my .php?
@Santiago you need to decode and save. you can find solution here stackoverflow.com/questions/11511511/…
Base64 is easy but very bandwidth expensive... upto 30% rise in data to send... wouldnt recommend
10

I have tried all the above but none worked for me to upload a file to a server.

After a deep search, I got a plugin the same as Dio.

The following code uploads a file to a server.

uploadFileFromDio(UserProfile userProfile, File photoFile) async { var dio = new Dio(); dio.options.baseUrl = url; dio.options.connectTimeout = 5000; //5s dio.options.receiveTimeout = 5000; dio.options.headers = <Header Json>; FormData formData = new FormData(); formData.add("user_id", userProfile.userId); formData.add("name", userProfile.name); formData.add("email", userProfile.email); if (photoFile != null && photoFile.path != null && photoFile.path.isNotEmpty) { // Create a FormData String fileName = basename(photoFile.path); print("File Name : $fileName"); print("File Size : ${photoFile.lengthSync()}"); formData.add("user_picture", new UploadFileInfo(photoFile, fileName)); } var response = await dio.post("user/manage_profile", data: formData, options: Options( method: 'POST', responseType: ResponseType.PLAIN // or ResponseType.JSON )); print("Response status: ${response.statusCode}"); print("Response data: ${response.data}"); } 

8 Comments

Do you have any problems with content type? If I upload an image, I have to set the content type manually.
"content-type" is basically set in header of api, so you have to add a header param as content-type whatever set by api developer there Some common examples of content types are “text/plain”, “application/xml”, “text/html”, “application/json”, “image/gif”, and “image/jpeg”.
I am sending files (images, documents etc) from mobile device to Node.js API, which uses multer for storing files to MongoDB. I also have a web application which communicates with the same API. If I upload the image over my mobile app and Dio plugin, the mime-type on the server and in my mobgodb is "application/octet-stream". If I upload it over my web app, the mime-type is "image/jpeg". I do not need to set content-type manually in my web app.
I am uploading the image to the server but when I try to open an image that say's image is empty?
How do I receive it in my .php?
|
7

I found a working example without using any external plugin , this only uses

import 'package:http/http.dart' as http; 

Code

var stream = new http.ByteStream(DelegatingStream.typed(imageFile.openRead())); // get file length var length = await imageFile.length(); //imageFile is your image file Map<String, String> headers = { "Accept": "application/json", "Authorization": "Bearer " + token }; // ignore this headers if there is no authentication // string to uri var uri = Uri.parse(Constants.BASE_URL + "api endpoint here"); // create multipart request var request = new http.MultipartRequest("POST", uri); // multipart that takes file var multipartFileSign = new http.MultipartFile('profile_pic', stream, length, filename: basename(imageFile.path)); // add file to multipart request.files.add(multipartFileSign); //add headers request.headers.addAll(headers); //adding params request.fields['loginId'] = '12'; request.fields['firstName'] = 'abc'; // request.fields['lastName'] = 'efg'; // send var response = await request.send(); print(response.statusCode); // listen for response response.stream.transform(utf8.decoder).listen((value) { print(value); }); 

1 Comment

When I use your code it gives me error saying "image":["No file was submitted."]. Any ideas on how to solve that ?
6

Please try below solution

Future<String> uploadImageHTTP(file, url) async { var request = http.MultipartRequest('POST', Uri.parse(url)); request.files.add(await http.MultipartFile.fromPath('picture', file.path)); var res = await request.send(); return res.reasonPhrase; } 

2 Comments

I got this error. A value of type 'String?' can't be returned from the function 'uploadImageHTTP' because it has a return type of 'Future<String>'.
consider null safety changes
5

Consider using Flutter's Firebase Storage plugin -- it has features that could be useful for uploading large image files on a mobile connection.

I wrote the plugin, contributions and feedback are welcome!

2 Comments

Thanks, I was able to do it with http client library
"Use a Firebase plugin (that I wrote)", is not an answer to "How to upload image in Flutter?".
4

First of all choose your image from gallery or Camera

File _image; Future _getImage() async { var image = await ImagePicker.pickImage(source: ImageSource.gallery); setState(() { _image = image; }); } 

Now call the below function on button click or inside the _getImage() function. With the file i'm uploading other fields also you see in the saveInAttendance()

Don't forget to import package :

import 'package:dio/dio.dart'; import 'package:path/path.dart'; Future saveInAttendance( BuildContext context,String entryType,String mode) async { Dio dio = new Dio(); FormData formData = new FormData(); // just like JS formData.add("inimageFile", new UploadFileInfo(_image, basename(_image.path))); formData.add("compID",2); formData.add("company_id",2); formData.add("EntryType", entryType); formData.add("emp_code", 5); formData.add("Mode",mode); formData.add("location",""+_startLocation.latitude.toString()+"-"+_startLocation.longitude.toString()); dio.post(url_save_attendance, data: formData, options: Options( method: 'POST', responseType: ResponseType.json // or ResponseType.JSON )) .then((r) { setState(() { var data = json.decode(r.toString()); if(data["apiMessage"].contains('Saved')){ warningAlert("Attendance Saved", "Your attendance saved Successfully",context); } }); }).catchError(print); } 

For more Info you can visit Here

Comments

2

to get Body from request Instead of

response.stream.transform(utf8.decoder).listen((value) { print(value); }); 

I use:

String body=await response.stream.bytesToString() 

Comments

1

my working code below, based on @TejaDroid's sample, it upload one image via the AWS Gateway API with a lambda function behind to store the image into S3.

uploadImageWithhttp(File imageFile, int serialno) async { var postBody= { 'username': '[email protected]', "productid": "1000123", //TODO "imageno": serialno.toString(), 'image': imageFile != null ? base64Encode(imageFile.readAsBytesSync()) : '', }; final response = await http.post( constAWSAPIGateway_UploadImage[CONST_API_STAGE], headers: { //AuthUtils.AUTH_HEADER: _authToken 'Content-Type' : 'application/json', }, body: json.encode(postBody), ); final responseJson = json.decode(response.body); print(responseJson); } 

Comments

1
updateProfile() async { try { if (_formKey.currentState.validate()) { _formKey.currentState.save(); var dio = new Dio(); var formData = FormData.fromMap({ 'name': name, 'con_person_name': concernedPersonName, 'email': email, 'phone': phoneNumber, 'password': password, 'token': token, 'user_type': '3', 'license_no': licenceNumber, 'gstno': gstNumber, 'address': address, 'hospital_id': '102' 'image': await MultipartFile.fromFile(_image?.path, filename: _image.path.split('/').last ?? 'image.jpeg'), }); var response = await dio.post('$SERVER_ADDRESS/api/doctorregister', data: formData); print(response.statusCode); print(response.data); } } catch (error) { print(error.toString()); } } 

1 Comment

Along with your answer please. provide an explanation
1

I have found a easy way to upload images in flutter and then even receiving it on the server.

Flutter:

 MaterialButton( color: Colors.blue, child: Text( "Pick Image from Camera", style: TextStyle( color: Colors.white70, fontWeight: FontWeight.bold), ), onPressed: () async { final XFile? photo = await _picker.pickImage(source: ImageSource.camera); print(photo!.path); await uploadImage(photo.path); }, ), 

'uploadImage' function:

uploadImage(String filepath) async { var url = 'http://192.168.75.57:4000/upload'; var request = http.MultipartRequest('POST', Uri.parse(url)); request.files.add(await http.MultipartFile.fromPath("img", filepath)); request.fields['_id'] = "abcdef"; request.headers.addAll({ "Content-type": "multipart/form-data", }); var response = request.send(); return response; } 

On the server Side: (Nodejs) For this, first install multer (npm install multer)

const multer = require('multer'); const path = require('path') const storage = multer.diskStorage({ destination: './uploads', filename: (req, file, cb) => { cb(null, (new Date()).getTime().toString() + ".jpg"); }, }); const fileFilter = (req, file, cb) => { if (file.mimetype == "image/jpeg" || file.mimetype == "image/png") { cb(null, true); } else { cb(null, false); } }; const upload = multer({ storage: storage, limits: { fileSize: 1024 * 1024 * 6, }, fileFilter: fileFilter, }); 

Finally, honoring the request from flutter application: (In router.js)

router.post('/upload', upload.single("img"), function (req, res) { console.log("hit") console.log(req.body._id) res.send("ok") }) 

This method worked for me and I found it comparatively easier than other methods.

Comments

0

Import dio, image_picker library

 Future _onGalleryPressed() async { Future<File> image = ImagePicker.pickImage(source: ImageSource.gallery); setState(() { this._imageFile = image; }); File img = await image; Navigator.of(context).pop(); if (img != null) { //API CALL try { FormData formData = new FormData.from({"file": path}); var url = backendUrl + "/upload-image"; var token = await _getMobileToken(); Map<String, String> headers = { 'Authorization': 'Bearer $token', "Content-Type": "multipart/form-data", "X-Requested-With": "XMLHttpRequest" }; await dio.post(url, data: formData, options: Options( method: 'POST', headers: headers, responseType: ResponseType.json // or ResponseType.JSON )); Navigator.pop(context); } catch (e) {} } } 

1 Comment

How do I receive it in my .php?
0

If you want to upload it as a binary file.

 static uploadFile(File imageFile) async { final response = await http.post(postURL, body: imageFile.readAsBytesSync()); return json.decode(response.body); } 

Thank you

Comments

0

I have checked about it at multiple places finally i found a solution -

 var objToSend = { "file": await MultipartFile.fromFile( file.path, filename: filename, ), }; FormData formData = FormData.fromMap(objToSend); print(formData.files.toString()); Dio dio = new Dio(); await dio .post(_toSend, data: formData, options: Options( method: 'POST', headers: <String, String>{ "Content-Type": "application/json", "Access-Control-Allow-Origin": "*", "Authorization": 'Bearer ' + token }, )) .whenComplete(() { print('uploaded'); }).catchError((onError) { print('failed'); }); 

Comments

0
const express = require('express'); const mongoose = require('mongoose'); const multer = require('multer'); const app = express(); const port = 3000; // MongoDB connection mongoose.connect('mongodb://localhost:27017/yourdb', { useNewUrlParser: true, useUnifiedTopology: true, }).then(() => { console.log('Connected to MongoDB'); }).catch((err) => { console.error('MongoDB connection error:', err); }); // Define Image Schema const imageSchema = new mongoose.Schema({ imageData: Buffer, contentType: String, }); const Image = mongoose.model('Image', imageSchema); // Setup multer storage (store image in memory) const storage = multer.memoryStorage(); const upload = multer({ storage: storage }); // POST route to upload image app.post('/upload', upload.single('image'), async (req, res) => { try { const newImage = new Image({ imageData: req.file.buffer, contentType: req.file.mimetype, }); // Save the image to MongoDB await newImage.save(); res.status(200).send('Image uploaded successfully'); } catch (error) { res.status(500).send('Failed to store image'); } }); // Start the server app.listen(port, () => { console.log(`Server running at http://localhost:${port}`); }); import 'dart:io'; import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:image_picker/image_picker.dart'; import 'package:http/http.dart' as http; import 'package:http_parser/http_parser.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Image Upload', theme: ThemeData( primarySwatch: Colors.blue, ), home: ImageUploadPage(), ); } } class ImageUploadPage extends StatefulWidget { @override _ImageUploadPageState createState() => _ImageUploadPageState(); } class _ImageUploadPageState extends State<ImageUploadPage> { final ImagePicker _picker = ImagePicker(); // Variable to store picked image XFile? _image; // Function to pick an image Future<void> _pickImage() async { final XFile? image = await _picker.pickImage(source: ImageSource.gallery); if (image != null) { setState(() { _image = image; }); } } // Function to upload image to Node.js server Future<void> _uploadImage() async { if (_image == null) return; final bytes = await _image!.readAsBytes(); final uri = Uri.parse('http://192.168.1.5:3000/upload'); // Change to your server's local IP // Prepare the multipart request final request = http.MultipartRequest('POST', uri) ..files.add(http.MultipartFile.fromBytes( 'image', bytes, filename: 'image.jpg', contentType: MediaType('image', 'jpeg'), // Correct mime type for JPEG images )); try { final response = await request.send(); if (response.statusCode == 200) { print('Image uploaded successfully'); ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('Image uploaded successfully'))); } else { print('Image upload failed: ${response.statusCode}'); ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('Image upload failed'))); } } catch (e) { print('Error: $e'); ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('Error uploading image'))); } } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Image Upload'), ), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ if (_image != null) Image.file(File(_image!.path), height: 200, width: 200), SizedBox(height: 20), ElevatedButton( onPressed: _pickImage, child: Text('Pick Image'), ), SizedBox(height: 20), ElevatedButton( onPressed: _uploadImage, child: Text('Upload Image'), ), ], ), ), ); } } 

1 Comment

There is an answer that has already been upvoted many times by the community. Could you explain how your answer is better? Also, write a few words on how it works.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.