Wazza
Wazza

Reputation: 1885

Cache image as base64 then convert back to image

So I'm trying to cache an image if an upload fails, due to the current limitations of flutter I think I will have to save it to shared preferences as a base64 file, then get it from shared preferences, convert it back to an image then upload that to firebase storage. My current code looks like so:

void saveImageToCache(File image) async {
  List<int> imageBytes = image.readAsBytesSync();
  String base64Image = base64Encode(imageBytes); //convert image ready to be cached as a string

  var cachedImageName = "image $fileName";
  instance.setString(cachedImageName, base64Image); // set image name in shared preferences

  var retrievedImage = instance.getString(cachedImageName);// once a connection has been established again, get the image file from the cache and send it to firebase storage as an image
  storageReference.putData(retrievedImage, StorageMetadata(contentType: 'base64'));

  var prefix = "data:image/png;base64,";
  var bStr = retrievedImage.substring(prefix.length);
  var bs = Base64Codec.codec.decodeString(bStr);
  var file = new File("image.png");
  file.writeAsBytesSync(bs.codeUnits);
  uploadTask = storageReference.child(fileName).putFile(file, const StorageMetadata(contentLanguage: "en"));

}

This is failing for me at var bStr = retrievedImage.substring(prefix.length); with error type 'String' is not a subtype of type 'Uint8List' where and im still not sure if im doing the right thing.

Any help would be great thanks.

Upvotes: 1

Views: 1569

Answers (1)

Edman
Edman

Reputation: 5605

I wouldn't recommend storing binary files to shared preferences. Especially since you're building an image cache.

I'd just store them to a file.

  Future<File> saveFile(File toBeSaved) async {
    final filePath = '${(await getApplicationDocumentsDirectory()).path}/image_cache/image.jpg';
    File(filePath)
      ..createSync(recursive: true)
      ..writeAsBytes(toBeSaved.readAsBytesSync());
   }

This uses getApplicationDocumentsDirectory() from the path provider package.

Upvotes: 3

Related Questions