Search code examples
fluttersqfliteflutter-iosflutter-image

Cannot save the Image into the Device in Flutter?


I am trying to save an image in local device using sqllite. I am using the edge_detection library to get the cropped image path and trying save it into the device. This is my table:

class DBHelper {
  static Future<Database> database() async {
    final dbPath = await sql.getDatabasesPath();
    return sql.openDatabase(path.join(dbPath, 'locations.db'),
        onCreate: (db, version)  => _createDb(db), version: 1);}
  static void _createDb(Database db) {
    db.execute('CREATE TABLE location(id INTEGER PRIMARY KEY AUTOINCREMENT, title TEXT, image TEXT)');
    db.execute('CREATE TABLE images(id INTEGER PRIMARY KEY AUTOINCREMENT, Image TEXT, fileId INTEGER)');
  }

My insert code is:

void addImage(int file_id, File pic) {
    final newpicture = Picture(file_id: file_id, image: pic);
    _items.add(newpicture);
    notifyListeners();
    DBHelper.insert('images', {
      'Image': newpicture.image.path,
      'fileId': newpicture.file_id,
    });
  }

And I am getting the data with this code:

Future<void> fetchAndSetPlaces() async {
    final dataList = await DBHelper.getData('images');
    print(dataList);
    _items = dataList
        .map(
          (item) => Picture(
            image:File(item['Image']),
            file_id: item['fileId'],
          ),
        )
        .toList();
    notifyListeners();
  }
}

My model like this:

class Picture{
  int? id;

  final int file_id;
  final File image;

  Picture({required this.file_id,required this.image});



}

And this is how i use the function to get imagepath:

Future<void> getImage(int? file_id) async {
    String? imagePath;
    // Platform messages may fail, so we use a try/catch PlatformException.
    // We also handle the message potentially returning null.
    try {
      imagePath = (await EdgeDetection.detectEdge);
      print("$imagePath");
    } on PlatformException {
      imagePath = 'Failed to get cropped image path.';
    }

    // If the widget was removed from the tree while the asynchronous platform
    // message was in flight, we want to discard the reply rather than calling
    // setState to update our non-existent appearance.
    if (!mounted) return;

    var directory = await getApplicationDocumentsDirectory();
    String path=directory.path;



    setState(() {
      _imagePath = imagePath;
    });
    print(_imagePath);

    Provider.of<Images>(context, listen: false)
        .addImage(file_id!, File(_imagePath!));
  }

And this is how I am getting the data in widget:

Consumer<Images>(
                  builder: (ctx, titles, ch) => GridView.builder(
                      itemCount: titles.items.length,
                      gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                        crossAxisCount: 3,
                        mainAxisSpacing: 2,
                        crossAxisSpacing: 2,
                      ),
                      itemBuilder: (ctx, index) {
                        return Column(
                          children: <Widget>[
                            Expanded(
                              child: Container(
                                padding:EdgeInsets.symmetric(vertical: 10,horizontal:10),
                                  child: Image.file(titles.items[index].image)),

This is after adding picture: This is after adding picture This is after closing and reopening the application: enter image description here

The problem is that I can see the picture after I took the photo but when i close the application and later reopen it again there is no picture to show.How can i solve this problem?Thanks in advance.

Update: So when i ran my code in release mode there was no problem.I think debug mode is the problem.


Solution

  • first step change datatype of image in database to BLOB db.execute('CREATE TABLE images(id INTEGER PRIMARY KEY AUTOINCREMENT, Image BLOB, fileId INTEGER)');

    Second step change datatype in your model to Uint8List

    final Uint8List image;

    finally when you read image ,read it as Uint8List