Reputation: 69410
My flutter app uses the camera
package to take a photo, which I save to the application's data directory (obtained from path_provider
and the getApplicationDocumentsDirectory()
function).
How can I save this image file into the phone photo gallery? I've noticed the image_picker
package allows reading from the gallery, but how can I write to it?
Upvotes: 39
Views: 59075
Reputation: 469
await Gal.putImage(path);
await Gal.putVideo(path);
Incidentally, the temporary directory can be obtained without using path_provider, just with this code
Directory.systemTemp.path;
Some people try to save the media in the project's asset folder, so I leave the code for that as well.
final byteData = await rootBundle.load('assets/image.jpg');
final file = await File('${Directory.systemTemp.path}${path.replaceAll('assets', '')}').create();
await file.writeAsBytes(byteData.buffer.asUint8List(byteData.offsetInBytes, byteData.lengthInBytes));
await Gal.putImage(file.path);
It works for both Android and iOS. More info can be found in the example of the gal package. Thank you.
Upvotes: 27
Reputation: 40513
Unfortunately flutter doesn't currently expose that functionality. It does seem like a candidate for a plugin though.
If you're motivated enough, you could use platform channels to communicate from flutter to native Android (and iOS) code, from which you can get full access the gallery. Bonus points if you make it into a plugin and publish it!
Upvotes: 12
Reputation: 518
https://pub.dev/packages/gallery_saver
this plugin saves images and video to gallery/photos.
You just need to provide it with path to temp file that you got from Camera(or even network url, it also works):
GallerySaver.saveVideo(recordedVideo.path);
GallerySaver.saveImage(recordedImage.path);
**** DEPRICATED use something else.
Upvotes: 21
Reputation: 2751
This is working for me-
// https://pub.dev/packages/path_provider
Future<String> getExtStorageOrDownloadsDirPath() async {
final documentsDir = await getApplicationDocumentsDirectory();
if (Platform.isAndroid) {
//final extStorageDir = await getExternalStorageDirectory();
//return extStorageDir?.path ?? documentsDir.path;
return '/storage/emulated/0/Download';
} else {
final downloadsDir = await getDownloadsDirectory();
return downloadsDir?.path ?? documentsDir.path;
}
}
Once you get path, you can save like this
if (imageBytes != null) {
XFile xFile = XFile.fromData(imageBytes, mimeType: 'image/png');
String documentsDirPath = await getExtStorageOrDownloadsDirPath();
String filePath =
'$documentsDirPath/${widget.bannerData.creativeTitle?.split(' ').join('-')}.png';
if (await Permission.storage.request().isGranted) {
// Either the permission was already granted before or the user just granted it.
xFile.saveTo(filePath);
showToastMessage('Saved to $filePath');
}
}
Upvotes: 2
Reputation: 57
There is a workaround, I made it worked by specifying path to "/storage/emulated/0/DCIM/YOUR_FOLDER/YOUR_FILE_NAME" then it will be saved outside of support package directory then image appears in Gallery. You can use any image saver plugin just provide that hardcoded path.
Upvotes: 1
Reputation: 389
I had to search a lot, but I found a very useful solution to save the image in the cell phone's photo gallery and get the absolute path to use it the way you want. For this example I used a result obtained from saving an image in the photo gallery, however it could also work to read other files, obviously making the changes that you see necessary, I hope it will help you uri_to_file image_gallery_saver
import 'dart:io';
import 'package:image_gallery_saver/image_gallery_saver.dart';
import 'package:uri_to_file/uri_to_file.dart';
Future<File> saveImage(File image, String identifier) async {
try {
var result = await
ImageGallerySaver.saveImage(image.readAsBytesSync(),
quality: 60, name: identifier +
"-${DateTime.now().toIso8601String()}");
print(result);
File file = await toFile(Uri.parse(result['filePath']));
print(file);
return file;
} catch (e) {
print(e);
return new File('assets/img/default-img.jpg');
}
}
// example
saveImage(File("path/image/img223.jpg"),"img-test");
// or
Upvotes: 1
Reputation: 439
There is a package which you can use to update the gallery by giving the path of the image or the video. The advantage of this over the other packages is that you can save files even in a sd card. The file will not be saved twice when you try to add media to gallery which are already saved to the device. This is the link to the package. https://pub.dev/packages/media_scanner
MediaScanner.loadMedia("Path to the file or directory"); // This will update the gallery
This is Android only
Upvotes: 1
Reputation: 19
I have been searching for this answer for a while but fortunately, I am able to save files to gallery with this code:
ByteData byteData = await rootBundle.load('assets/images/example.png');
File file = await File('/storage/emulated/0/Android/media/<your app package>/<App title/folder>/example.png').create(recursive: true);
await MediaStore.saveImage(byteData.buffer.asUint8List(byteData.offsetInBytes, byteData.lengthInBytes));
This will save your image to the device and your device gallery.
This only works for Android
Thanks.
Upvotes: 1
Reputation: 3267
There is a plugin that supports this.
https://pub.dev/packages/image_gallery_saver
I have tested it and it's working fine.
Upvotes: 7
Reputation: 2092
I made the plugin. Please try it if you like.
https://pub.dartlang.org/packages/image_downloader#-readme-tab-
update
I will explain how to use.
Add this to your package's pubspec.yaml file:
dependencies:
image_downloader: ^0.9.0
After that, specify permission for each devices.
Just write the following and image will be saved.
ImageDownloader.downloadImage(url);
Upvotes: 5