Duncan Jones
Duncan Jones

Reputation: 69410

How to save an image to the photo gallery using Flutter?

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

Answers (10)

okok
okok

Reputation: 469

2025

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.

Upvotes: 27

rmtmckenzie
rmtmckenzie

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

jelenap
jelenap

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

Varun Kumar
Varun Kumar

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

ITcians
ITcians

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

ArmandoHackCode
ArmandoHackCode

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

LovinduLI
LovinduLI

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

Shivam Chouhan
Shivam Chouhan

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

Yugene
Yugene

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

ko2ic
ko2ic

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

Related Questions