Flutter: Display image from URI string or File object

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?

3 answers

  • answered 2019-05-21 09:32 Gunhan

    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);
    }
    

  • answered 2019-05-21 11:32 NIKHAT SHAIKH

    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))
    

  • answered 2019-05-21 13:27 Bisclavret

    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.