I am having a problem. I have a Drawer in Flutter App and I want to implement a feature where you can pick a photo from gallery. Thats the easy part. But i want to save this photo in the preferences and load it when the App starts again. The imageFromPreferences variable have to be an Future to use it in the preferenceImage() Future builder. I got not idea how to it after hours of research. Maybe its the total wrong approach and you got a different idea.

import 'dart:io';
import 'dart:ui';
import 'package:firstapp/database/database.dart';
import 'package:firstapp/views/note.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/painting.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart';
import 'package:image_picker/image_picker.dart';
import 'package:firstapp/Utility/Utility.dart';

class NoteList extends StatefulWidget {
  @override
  NoteListState createState() {
    return new NoteListState();
  }
}

class NoteListState extends State<NoteList> {
  Future<File> imageFile;
  Image imageFromPreferences;

  pickImageFromGallery(ImageSource source) {
    setState(() {
      imageFile = ImagePicker.pickImage(source: source);
    });
  }

  loadImageFromPreferences() {
    Utility.getImageFromPreferences().then((img) {
      setState(() {
        imageFromPreferences = Utility.imageFromBase64String(img);
      });
    });
  }

  Widget preferenceImage() {
    return FutureBuilder<Image>(
      future: loadImageFromPreferences(),
      builder: (BuildContext context, AsyncSnapshot<Image> image) {
        print(image);
        if (image.connectionState == ConnectionState.done && image.hasData) {
          return image.data;
        } else {
          return Text("error");
        }
      },
    );
  }

  Widget imageFromGallery() {
    return FutureBuilder<File>(
      future: imageFile,
      builder: (BuildContext context, AsyncSnapshot<File> snapshot) {
        if (snapshot.connectionState == ConnectionState.done &&
            snapshot.hasData) {
          Utility.saveImageToPreferences(
              Utility.base64String(snapshot.data.readAsBytesSync()));
          return Image.file(
            snapshot.data,
          );
        }
        return null;
      },
    );
  }

  finalPicker() {
    if (imageFromGallery() == null) {
      return preferenceImage();
    } else if (imageFromGallery() != null) {
      return imageFromGallery();
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Taking Notes')),
      drawer: Drawer(
        child: ListView(
          children: <Widget>[
            UserAccountsDrawerHeader(
              accountEmail: Text('[email protected]'),
              accountName: Text('Max'),
              decoration: BoxDecoration(
                color: Theme.of(context).primaryColor,
              ),
              currentAccountPicture: GestureDetector(
                onTap: () {
                  pickImageFromGallery(ImageSource.gallery);
                },
                child: Column(
                  children: <Widget>[finalPicker()],
                ),
              ),
            ),
            Container(
              padding: EdgeInsets.all(20.0),
              child: Text("Locked files"),
              color: Theme.of(context).primaryColor,
            ),
          ],
        ),
  ),

This is how I save the Image as a String in the preferences. Maybe I could instead save it in a file?

import 'dart:async';
import 'dart:convert';

class Utility{

  static const String IMG_KEY = "IMAGE_KEY";

  static Future<bool> saveImageToPreferences(String value) async {
    final SharedPreferences preferences = await SharedPreferences.getInstance();
    return preferences.setString(IMG_KEY, value);
  }

  static Future<String> getImageFromPreferences() async{
    final SharedPreferences preferences = await SharedPreferences.getInstance();
    return preferences.getString(IMG_KEY);
  }

  static String base64String(Uint8List data) {
    return base64Encode(data);
  }

  static Image imageFromBase64String(String base64String){
    return Image.memory(base64Decode(base64String), fit: BoxFit.fill);
  }
}


Solution 1: user9683896

// using your method of getting an image
final File image = await ImagePicker.pickImage(source: imageSource);

// getting a directory path for saving final String path = await getApplicationDocumentsDirectory().path;

// copy the file to a new path final File newImage = await image.copy('$path/image1.png');

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

you can store this path in your shared preference. here you make copy in root directory and then store path of that image.


Solution 2: user9683896

also you can used this plugin https://pub.dev/packages/image_picker_saver

[image_picker_saver][1]