Future getImage() async {
var image = await ImagePicker.pickImage(source: ImageSource.camera);
setState(() {
_image = image;
print("IMG:" + _image.toString());
});
setPrefs() ;
}
Future setPrefs() async {
_base64 = base64.encode(_image.readAsBytesSync());
print(_base64);
final prefs = await SharedPreferences.getInstance();
prefs.setString(IMAGE_KEY, _base64);
}
The readAsBytesSync()
method works fine on Android but too slow in iOS. So how can I move this code to a new background thread?
1. Use Future
You can use the async version of the readAsBytes
.
So instead of:
final imageData = _image.readAsBytesSync();
_base64 = base64.encode(imageData);
You could have:
final imageData = await _image.readAsBytes();
_base64 = base64.encode(imageData);
2. Use Isolate
In your code, it may not necessarily be the readAsBytes
line that is slow. It might be the base 64 encodings of the image. If that's the case, you could put the entire computation into a separate isolate. There is a convenient method compute that you can use.
// This needs to be a global function
encodeImage(File imageFile) {
return base64.encodeimageFile.readAsBytesSync());
}
Future setPrefs() async {
_base64 = await compute(encodeImage, _image);
print(_base64);
final prefs = await SharedPreferences.getInstance();
prefs.setString(IMAGE_KEY, _base64);
}
In addition, it is worth mentioning that SharedPreferences
(for Android, aka, NSUserDefaults
on iOS) is designed to store small user settings. It is not designed for storing the images, which could be megabytes big. It is better to copy the image file into the app's document folder, and only store the filename in the SharedPreferences
.