How to save an image to the photo gallery using Flutter?
Asked Answered
P

10

34

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?

Plafond answered 23/4, 2018 at 18:29 Comment(1)
Hey, it's been more than 2 years, did you find any plugin that does what you required(I don't know how to use platform channels)Gibeon
C
10

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!

Cord answered 23/4, 2018 at 19:23 Comment(2)
As far as I know there's no plugin yet for that. I have added this exact case as an example of relatively easy plugin to be implemented, with detailed steps necessary for doing it in my post on medium.com/p/contributing-to-flutter-part-2-46092dc4417e.Groats
Is there any plugin for that now?Bidentate
B
20

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.

Bawdy answered 7/8, 2019 at 9:43 Comment(10)
my images have path like "assets/images/my image.jpg" its not working... Will you pls tell me the type of recorded.path. Whats it tyep like File or binary data or string etc.Inhuman
Is it possible to list the media from the gallery after saving?Electrostriction
Unfortunately this fails on Android 11Manciple
It fails on android 11 due to scoped storage, don't know which package dev will solve this problem first, but waiting for itGibeon
I get wrong timestamp saving GIF to photo album on iOS 14.Equestrienne
Correction about my above comment... I get wrong timestamp trying to save GIF for both image_gallery_saver and gallery_saver, it was resolved by adding creationTime to PHAssetChangeRequestEquestrienne
Now we also have a bit more consistent fork of it: pub.dev/packages/add_to_galleryIdealist
Both "add_to_gallery" and "gallery_saver" are outdated.Acotyledon
We should use the gal package instead in 2023.Taylor
can anybody name "something else"Leland
T
20

2024

gallery_saver and its forked packages (like image_gallery_saver) are outdated.
We should use gal instead.
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.

Taylor answered 26/6, 2023 at 11:50 Comment(2)
This should be the accepted answer. The Gal plugin also work on all the mainstream platforms except web. +1Clobber
Can we pass response body to it? like i have a post request for downloading an image n saving it in gallery. Url plus body: {"image": image.jpg}Mercado
C
10

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!

Cord answered 23/4, 2018 at 19:23 Comment(2)
As far as I know there's no plugin yet for that. I have added this exact case as an example of relatively easy plugin to be implemented, with detailed steps necessary for doing it in my post on medium.com/p/contributing-to-flutter-part-2-46092dc4417e.Groats
Is there any plugin for that now?Bidentate
F
7

There is a plugin that supports this.

https://pub.dev/packages/image_gallery_saver

I have tested it and it's working fine.

Figure answered 24/6, 2019 at 3:58 Comment(3)
Also - like gallery_saver - fails on Android 11Centerpiece
works on android now but fails for iOS :(! Opened an issue on github: github.com/CarnegieTechnologies/gallery_saver/issues/93Centerpiece
actually the saveImage method not works when you specify a name of image. the image name remains in the ios format IMG_XXX. i have open an issue on github but there are many issue remained open for this issue.Degreeday
B
5

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);
Bughouse answered 6/11, 2018 at 15:10 Comment(2)
I implemented it and ImageDownloader return true, but where is the file located?Ailis
If download image has CreateDate of exif, there is in the date in Photo app(iOS) or download directory(Android).Bughouse
B
2

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');
  }
}
Babblement answered 27/5, 2023 at 7:4 Comment(0)
O
1

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.

Ontology answered 3/8, 2021 at 6:50 Comment(1)
where is MediaStore from?Clobber
C
1

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

Crossways answered 10/9, 2021 at 14:50 Comment(0)
C
1

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
Cantabrigian answered 16/11, 2021 at 0:39 Comment(0)
M
1

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.

Monty answered 13/4, 2022 at 20:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.