Get The Image variable from the File Path and upload to backend in FileFormat in Flutter

1.9k views Asked by At

I'm new to flutter and in an app I'm building I use ImagePicker plugin. with that the file path image is viewed in my app after I get it from camera/gallery. the image.path is like this

/storage/emulated/0/Android/data/.../files/Pictures/234d9437-8652-48de-a2b6-711b5f8b702d3492716976084944343.jpg

I need to get the image "234d9437-8652-48de-a2b6-711b5f8b702d3492716976084944343.jpg" part from that and send it to a backend db. I need to convert this before sending. Backend only accept Images in FileFormat.

How can get the image from the file path. in this case it's the variable _imageURI. Then from that retrieve the image and convert it into a FileFormat. After that I need to pass it to a Backend using a json POST request.

In my json request I have a field for 'image': that I need to set the value got from image selected in file format and set to there. how can do this? can someone explain me with a code ? much appreciated.

My Code

File _imageURI;
Future _getImageFromCamera() async {
var petImage = await ImagePicker.pickImage(source: ImageSource.camera); //or gallery
setState(() {
      _imageURI = petImage;
      print(_imageURI.path);
  }
}

Image Viewed as

Container(
  width: 120.0,
  height: 120.0,
  decoration: new BoxDecoration(
    shape: BoxShape.circle,
    image: new DecorationImage(
      fit: BoxFit.cover,
      image: new FileImage(
        _imageURI,
        scale: 1.0,
      ),
    ),
  ),
),

Json Request

dogData = {
 {
  "user_email": "[email protected],
  "user_token": "thisistoken",
  "pet": {
    "age": "integer",
    "birth_date": "%d %b %Y (01 JAN 1996)",
    "image": "!Swagger doesn't allow to put file upload. Use formdata instead of base64 in frontend module.",
    "name": "string",
    "sex": "string",
    "user_id": "id"
  }
}

My API call

final pet = await CallApi().createThePet(dogData, 'pets/create');
////
Future<dynamic> createThePet(data, apiUrl) async{
    var fullUrl = _baseUrl + apiUrl; // + await _getToken();
    final response = await http.post(fullUrl, body: jsonEncode(data), headers: _setHeaders());
....
2

There are 2 answers

3
Abhijith On

Hope this helps,it is working fine with my project Install imagepicker,mime,http and import it

import 'package:mime/mime.dart';
import 'package:http/http.dart' as http;
import 'package:http/http.dart';
import 'package:http_parser/http_parser.dart';
import 'package:image_picker/image_picker.dart';

Initialize variable

File _image;
final Imagepicker = ImagePicker();

View for showing image after selecting

Container(
                    width: 350,
                    height: 250,
                    decoration: BoxDecoration(
                        borderRadius: BorderRadius.circular(15.0),
                        border: Border.all(
                            color: Colors.deepOrangeAccent[400], width: 1.0)),
                    child: GestureDetector(
                      child: ClipRRect(
                        borderRadius: BorderRadius.circular(15.0),
                        child: Container(
                          width: 350,
                          height: 250,
                          child: _image == null
                              ? Text('No image selected.')
                              : Image.file(
                                  _image,
                                  fit: BoxFit.cover,
                                ),
                          decoration: new BoxDecoration(
                            borderRadius: BorderRadius.circular(10.0),
                            color: Colors.white,
                          ),
                        ),
                      ),
                      onTap: () {
                        getImage();
                      },
                    ),
                  ),

ImagePicker from camera

    Future getImage() async {
        PickedFile image =
        await Imagepicker.getImage(source: ImageSource.camera, maxHeight: 1000);
    
        setState(() {
          _image = File(image.path);
        });
  }

Submit Function

     void submit(File image, String descrption) async {
          try {
                ///Spilits the path and returns only the filename and type
                
 final mimeTypeData =lookupMimeType(image.path, headerBytes: [0xFF, 0xD8]).split('/');

    ///Url of your api

          final request =new http.MultipartRequest("POST", Uri.parse(Urls.ImageInsert));

    ///replace AreaImage with your database value

          final file = await http.MultipartFile.fromPath('AreaImage', 
          image.path,contentType: MediaType(mimeTypeData[0], mimeTypeData[1]));

    ///In case there is text fields or other details use like this
          request.fields['user_email'] = "Email";
          request.fields['user_token'] = "thisistoken";
         
          request.files.add(file);

          StreamedResponse response = await request.send();

        //waiting for response

        response.stream.transform(utf8.decoder).listen((value) {

          //Response can be pass with map object to alertbox

          Map<String, dynamic> map = jsonDecode(value);
          try {
          
  // hide progrssbar
            pr.hide();

            showDialog(
              context: context,
              builder: (BuildContext context) {
                return AlertDialog(
                  title: Text("Alert"),
                  //here we show response message from api/or you can show your own message 
                 here
                  content: Text(map['message']),
                  actions: [
                    FlatButton(
                      child: Text("Close"),
                      onPressed: () {
                        //Do Something here
                      },
                    )
                  ],
                );
              },
            );
          } catch (e) {
            e.toString();
          }
        });
      }
      
             }
         
         }

You can checkout my github for image upload with either gallery or cameragithub

1
Manish On

The term you are looking for is called Multi-Part. There isn't any definite piece of code for that in flutter so i am posting an example snippet.

Future<void> _uploadImage(File image) async {
String tempURL = https://YOUR_WEBSITE/upload";
var request = new http.MultipartRequest("POST", Uri.parse(tempURL));
request.headers["authorization"] = YOUR_TOKEN_HERE;
// prepare file to send.
var profilePhoto = http.MultipartFile(
    'upload', image.readAsBytes().asStream(), image.lengthSync(),
    filename: image.path);
request.files.add(profilePhoto);
try {
  // send files to server.
  var response = await request.send();
  if (response.statusCode == 200) {
    // now we will update the data with the
    response.stream.bytesToString().asStream().listen((data) {
      _updatePhoto(data);
    });
  } else {
    print("res status code in upload func : ${response.statusCode}");
  }
} catch (error) {
  print("Error : $error");
}

}