58

I am actually trying to convert an image picked by ImagePicker in flutter to base64 image. I am always getting the error.

FileSystemException: Cannot open file, path = 
'file:///storage/emulated/0/Download/Abid_Wipro_neemuchwala1- 
770x433.jpg' (OS Error: No such file or directory, errno = 2)
E/flutter ( 5042): #0      _File.throwIfError 
(dart:io/file_impl.dart:628)
E/flutter ( 5042): #1      _File.openSync 
(dart:io/file_impl.dart:472)
E/flutter ( 5042): #2      _File.readAsBytesSync 
(dart:io/file_impl.dart:532)

the code i am using is this one.

     File fileData;
   /////////////...........


      new Container(
            child: new FutureBuilder<File>(
              future: imageFile,
              builder: (BuildContext context, AsyncSnapshot<File> snapshot) {
                if (snapshot.connectionState == ConnectionState.done &&
                    snapshot.data != null) {
                  fileData = snapshot.data;


                  return new Container(
                    height: MediaQuery.of(context).size.height / 2,
                    width: MediaQuery.of(context).size.width,
                    margin: const EdgeInsets.all(4.0),
                    decoration: new BoxDecoration(
                      image: new DecorationImage(
                        image: new FileImage(snapshot.data,),
                        fit: BoxFit.cover
                      ),
                    ),
                  );
                } else if (snapshot.error != null) {
                  return new Column(children: <Widget>[
                    centerWidget('Choose Image or Audio or Video'),
                    _circleAvatar()
                  ]);
                } else {
                  return new Column(children: <Widget>[
                    centerWidget('Choose Image or Audio or Video'),
                    _circleAvatar()
                  ]);
                }
              },
            ),
          ),
/////////////////

    File imageFile = new File(widget.fileData.uri.toString());
    List<int> imageBytes = imageFile.readAsBytesSync();
    String base64Image = base64Encode(imageBytes);

Please, can someone tell me where is it that i am making a mistake .

Many thanks, Mahi

Mahi
  • 5,726
  • 13
  • 31
  • 41
  • The file you try to read doesn't exist or the app doesn't have permission to read. The error doesn't seem related to base64 – Günter Zöchbauer Apr 26 '18 at 06:50
  • Thanks@GünterZöchbauer but the file is present in the path specified , and is displayed on the phone but cannot convert the image to base64 – Mahi Apr 26 '18 at 06:53
  • It's still not related to base64 when the error says that the file can't be read. – Günter Zöchbauer Apr 26 '18 at 06:55
  • Hi @zoechi is there any other solution so that i can just convert the image file to base64 encoding. – Mahi Apr 26 '18 at 06:56
  • You can't convert something that you don't have access to :D – Günter Zöchbauer Apr 26 '18 at 06:58
  • @zoechi i am thinking i just picked an image from gallery and want to convert the picked image to base64 is this something which we cannot do in flutter or dart? – Mahi Apr 26 '18 at 07:02
  • Why do you keep talking about converting. First you need to be able to access the file and it's content. Before you are not able to do that there is absolutely no point in talking about converting. – Günter Zöchbauer Apr 26 '18 at 07:08
  • sorry @zoechi . My requirement in the application is to take a picture or pick one from gallery and then upload this image to service which uses the sqlite database. Before sending a request I need to convert this to base64 but as from this conversation you are saying i am trying to convert something i don't have access to . I think i need to find a different solution to this one then. – Mahi Apr 26 '18 at 07:18
  • ... or figure out why your app can't read from a file you claim is there. I haven't tried to read from the download directory myself yet. – Günter Zöchbauer Apr 26 '18 at 07:24
  • the code is failing at this line ```List imageBytes = imageFile.readAsBytesSync();``` . am i doing something wrong here.? – Mahi Apr 26 '18 at 07:28
  • I see 2 possible issues as mentioned above. The file with the given path doesn't exist (perhaps path wrong in some way) or the app doesn't have read access. If you could render the image using an `Image` widget, then it's probably not a permission issue. – Günter Zöchbauer Apr 26 '18 at 07:32
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/169832/discussion-between-mahi-and-gunter-zochbauer). – Mahi Apr 26 '18 at 07:34
  • 2
    Thanks @zoechi you are amazing the path was modified, i removed the line ```File imageFile = new File(widget.fileData.uri.toString());``` and chnaged my code as ```List imageBytes = widget.fileData.uri.readAsBytesSync();``` and it's working now. – Mahi Apr 26 '18 at 08:22

9 Answers9

101

I just changed my code as follows,

import 'dart:convert';

List<int> imageBytes = widget.fileData.readAsBytesSync();
print(imageBytes);
String base64Image = base64Encode(imageBytes);

and this is working fine now.

It is better to read it asynchronously as the image can be very large which may cause blocking of the main thread

 List<int> imageBytes = await widget.fileData.readAsBytes();
Vassily
  • 5,263
  • 4
  • 33
  • 63
Mahi
  • 5,726
  • 13
  • 31
  • 41
31

If you import the io package and convert:

import 'dart:io' as io;
import 'dart:convert';

you can simply change the image to string :

final bytes = io.File(imageBytes.path).readAsBytesSync();

String img64 = base64Encode(bytes);
Alessio
  • 15
  • 3
Lokesh
  • 357
  • 5
  • 14
13

In my case, i first selected the image using image_picker then use these line of code to convert the image to base64.

 final bytes = File(image!.path).readAsBytesSync();
                          String base64Image =  "data:image/png;base64,"+base64Encode(bytes);

                          print("img_pan : $base64Image");

image_picker code :

  final ImagePicker _picker = ImagePicker();
  XFile? image;

                  Container(
                    margin: const EdgeInsets.all(15.0),
                    padding: const EdgeInsets.all(3.0),
                    decoration: BoxDecoration(
                        border: Border.all(color: Colors.black),
                      borderRadius: BorderRadius.all(Radius.circular(5.h))
                    ),
                    child:InkWell(
                    onTap: () async {
                      image = await _picker.pickImage(
                          source: ImageSource.gallery);
                      setState(() {});
                    },
                    child: image != null
                        ? Image.file(
                            File(image!.path),
                            height: 100.h,
                            width: 100.w,
                          )
                        : Image.asset(
                            'assets/image_icon.png',
                            height: 100.h,
                            width: 100.w,
                      fit: BoxFit.fill,
                          ),
                  ),),
Tarun Yadvendu
  • 230
  • 3
  • 11
3

In case you are trying to manage image/file uploads using Flutter Web, https://pub.dev/packages/file_picker is a better package to go with.

As we know, dart:io is not supported on Flutter Web and throws Unsupported operation: _Namespace error. Hence, using File and reading file's bytes was not an option. Luckily, the package provides API to convert the uploaded image to Uint8List. Here is my implementation:

import 'package:file_picker/file_picker.dart';

...

FilePickerResult? pickedFile;

...

void chooseImage() async {
    pickedFile = await FilePicker.platform.pickFiles();
    if (pickedFile != null) {
      try {
        setState(() {
          logoBase64 = pickedFile!.files.first.bytes;
        });
      } catch (err) {
        print(err);
      }
    } else {
      print('No Image Selected');
    }
}

In case you need to display the local image right away, use Image.memory.

Image.memory(logoBase64!);
Taiyr Begeyev
  • 547
  • 1
  • 9
  • 12
2
Container(
                            child: new GestureDetector(
                              onTap: () async {
                                FocusScope.of(context)
                                    .requestFocus(new FocusNode());
                                await getImage();
                              },
                              child: new Center(
                                child: _image == null
                                    ? new Stack(
                                        children: <Widget>[
                                          new Center(
                                            child: new CircleAvatar(
                                              radius: 80.0,
                                              backgroundColor:
                                                  const Color(0xFF778899),
                                            ),
                                          ),
                                          new Center(
                                            child: Icon(
                                              Icons.perm_identity,
                                              size: 120,
                                            ),
                                          ),
                                        ],
                                      )
                                    : new CircleAvatar(
                                        radius: 60,
                                        child: ClipOval(
                                          child: Align(
                                            heightFactor: 0.8,
                                            widthFactor: 1.0,
                                            child: new Image.file(_image),
                                          ),
                                        ),
                                      ),
                              ),
                            ),
                          ),

Future getImage() async {
    UserService userRestSrv = UserService();

    PickedFile image = await ImagePicker().getImage(source: ImageSource.gallery, imageQuality: 50);

    if (image != null) {
      setState(() {
        _image = File(image.path);
      });

      final bytes = File(image.path).readAsBytesSync();

      String img64 = base64Encode(bytes);
      var responseProfileImage = await userRestSrv.updateImage(userId, img64);

      if (responseProfileImage != null && responseProfileImage.data['ResponseCode'] == "00")
        showMessage('Profile Image not uploaded', false);
    }
  }
Saad Ahmed
  • 700
  • 1
  • 8
  • 15
2

Here a simple function:

String convertIntoBase64(File file) {
List<int> imageBytes = file.readAsBytesSync();
String base64File = base64Encode(imageBytes);
return base64File;
}
Apoorv Pandey
  • 2,118
  • 2
  • 11
  • 13
1

I see that more than one has already answered the question. But I allow myself to put my solution and it works for me. I use file_picker: ^5.0.1

void openFileImageExplorer() async {
    //try {
      final pickedFile = await FilePicker.platform.pickFiles(
          allowedExtensions: ['jpg', 'jpeg', 'png', 'bmp', 'gif']
      );
      if (pickedFile == null) {
        return;
      }

    final file = pickedFile.files.first;

    final bytes = File(file.path!).readAsBytesSync();
    String img64 = base64Encode(bytes);
    setState(() {
      imageBase64 = img64;
    });

    logCat(img64);
    //} catch(ex, trace ){
    //  logError(ex, trace: trace);
    //}
}

And to display the image

Image.memory( base64Decode(imageBase64), fit: BoxFit.cover )

and I hope it will help...

Grafritz Design
  • 677
  • 6
  • 7
0
//this is dart code
final bytes = File(image!.path).readAsBytesSync();  
String base64Image = base64Encode(bytes);
print("imgbytes : $base64Image");

//this is flutter code for image picker
Future uploadAll() async {
var bytes = File(image!.path).readAsBytesSync();
String base64Image = base64Encode(bytes);
print('upload proccess started');

var apipostdata = {
  "title": contentController.text.toString().toUpperCase(),
  "book_image": base64Image,
  "book_type": _genderRadioBtnVal,
};
await http
    .post(Uri.parse('http://192.168.29.111:8000/api/book/add_book'),
        body: apipostdata)
    .then((response) {
  var returndata = jsonEncode(response.body);
  if (response.statusCode == 200) {
    print(returndata);
  } else {
    print('failed');
  }
}).catchError((err) {
  setState(() {
    err;
  });
});  }
Aravindhan
  • 11
  • 2
  • Please provide an explanation. Don't just post the code. See [How to answer](https://stackoverflow.com/help/how-to-answer). – tomasantunes Mar 11 '22 at 07:58
0

try to use Content-Type:charset=utf-8

in my case i use "Content-Type":"application/json; charset=utf-8" in header of my api

http.post(
        Uri.parse(url),
        body: myBody,
        headers: {"Content-Type":"application/json; charset=utf-8"},
      );

and var baseEncode= base64Encode(await file.readAsBytes()); for encoding

and it works for me