0

I am pulling an image from my gallery using ImagePicker like so:

ImageProvider backgroundImage;
String customImageFile;
File _image;

Future getImage() async {
  var image = await ImagePicker.pickImage(source: ImageSource.gallery);

  setState(() {
    _image = image;
  });

  customImageFile = _image.toString();
  SharedPreferences prefs = await SharedPreferences.getInstance();
  prefs.setString('customImageFile', customImageFile);
}

As you can see I am trying to store the URI of the image file into SharedPreferences, for persistence, and I am displaying it in my application like this:

Container(
  decoration: BoxDecoration(
    color: Colors.blueAccent,
      image: DecorationImage(
        image: _image == null ? backgroundImage :  FileImage(_image),
        fit: BoxFit.fill,
      ),
    ),
),

The issue is that I cannot seem to get the string value of customImageFile to actually load the image properly.

EDIT: Actually, I may have stumbled upon the cause, I hadn't noticed this until I used a print dump of the string. The actual string comes out to be this:

File: '/storage/emulated/0/Download/images.jpeg'

Instead of just:

'/storage/emulated/0/Download/images.jpeg'

It may just work if I can play with the String here. I am having trouble finding anything online about how to ignore the first 6 characters of a String. Was quite easy to do this in Java and in Visual Basic, but I can't find the method.

UPDATE: Have managed to reduce the string to:

'/storage/emulated/0/Download/images.jpeg'

By using:

customImageFile = customImageFile.substring(6);

But it now shows me this error:

Cannot open file, path = ''/storage/emulated/0/Download/images.jpeg'' (OS Error: No such file

So I can increase the substring value to 7 to remove the first apostrophe, how do I remove the last character of the String?

0

3 Answers 3

3

Ok so I finally got it working, and will provide the full sections of code here for anyone else that wants to do this:

Pull an image from the gallery using ImagePicker, and save the URI to SharedPreferences for persistence:

ImageProvider backgroundImage;
String customImageFile;
File _image;

  Future getImage() async {
   var image = await ImagePicker.pickImage(source: ImageSource.gallery);

   setState(() {
     _image = image;
   });

   customImageFile = _image.toString();
   SharedPreferences prefs = await SharedPreferences.getInstance();
   prefs.setString('customImageFile', customImageFile);
}

How to display the image in your build method, where backgroundImage is some placeholder you want to display before the user selects a custom file:

Container(
  decoration: BoxDecoration(
    color: Colors.blueAccent,
    image: DecorationImage(
      image: _image == null ? backgroundImage :  FileImage(_image),
      fit: BoxFit.fill,
    ),
  ),
),

Now customImageFile will not be an appropriate String value in order to find this image again from the gallery, so we need to edit the String to get it looking like something we can use. Original customImageFile String:

File: '/storage/emulated/0/Download/images.jpeg'

Fixing it up:

customImageFile = customImageFile.substring(6);
customImageFile = customImageFile.replaceAll("'", "");

Which now makes our String look like this:

/storage/emulated/0/Download/images.jpeg

Which is something we can now make use of with the previous suggestions, like so:

setState(() {
  _image =  File(customImageFile);
});

Tested and working fine. So now we can use the String we store in SharedPreferences to load up the previously selected image when the application launches. I drop a loadPreferences() method into initState() that handles all this kind of thing, works a treat.

Hope this helps someone because I couldn't find anything online about this.

Sign up to request clarification or add additional context in comments.

1 Comment

Your answer put me on the right track, so thanks for that. But instead of customImageFile = _image.toString() you should use customImageFile=_image.path which will give you what you're looking for without having to fix it with string manipulation
0

You should first check if the file exists at that path. Then you can load the image using the file constructor like below.

var file = File(imagePath);
if(file.existsSync()){
    return Image.file(file);
}

2 Comments

I see part of the issue now, my backGround variable was of type ImageProvider, which I needed for ImagePicker. I have fixed that now, but the error I am getting now is that the file doesn't exist...... I will update my question with the new info.
Original question updated, it may have been because it couldn't find the image. Something is wrong with the returned String value.
0

I included the Request Url directly in my Image.network() widget and it worked.

Here's the Code:

Widget _buildImage() {

    return FadeInImage(
      image: NetworkImage(
          'https://www.google.com/url?sa=i&source=images&cd=&ved=2ahUKEwik1L3zwqziAhXRZCsKHSWiDYsQjRx6BAgBEAU&url=https%3A%2F%2Funsplash.com%2Fsearch%2Fphotos%2Fcountry&psig=AOvVaw2SLubeS_2uHAib1sXXcfRX&ust=1558524613660099'),

    );
  }

And the image class has a file constructor for that-

https://docs.flutter.io/flutter/widgets/Image/Image.file.html

Image.file(File(path))

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.