gal

2.3.3

Flutter plugin to save images/videos to photos gallery with permission handling

Download archive

Readme

📢 Support Us

Please support our volunteer efforts by giving us a LIKE👍 and STAR⭐️.

🧠 DeepWiki Documentation

DeepWiki

📱 Supported Platforms

Android iOS macOS Windows Linux
Support SDK 21+ 11+ 11+ 10+ See: gal_linux

Support means that all functions have been tested manually or automatically whenever possible.

📸 Demo

iOS Android
Example

✨ Features

  • Open gallery
  • Save video
  • Save image
  • Save to album
  • Save with metadata
  • Handle permission
  • Handle errors
  • Comprehensive documentation and wiki

🚀 Getting Started

Add Dependency

Add the latest stable version of gal to your dependencies:

flutter pub add gal

iOS Setup

Add the following keys to ios/Runner/Info.plist:

  • <key>NSPhotoLibraryAddUsageDescription</key> Required
  • <key>NSPhotoLibraryUsageDescription</key> Required for iOS < 14 or saving to album

You can copy from example's Info.plist.

Android Setup

Add the following keys to android/app/src/main/AndroidManifest.xml:

  • <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="29" /> Required for API <= 29
  • android:requestLegacyExternalStorage="true" Required for saving to album in API 29

You can copy from example's AndroidManifest.xml.

[!WARNING] Android emulators with API < 29 require SD card setup. Real devices don't.

macOS Setup

Add the following keys to macos/Runner/Info.plist:

  • <key>NSPhotoLibraryAddUsageDescription</key> Required
  • <key>NSPhotoLibraryUsageDescription</key> Required for saving to album

You can copy from example's Info.plist.

[!WARNING] Flutter currently has a fatal problem for loading info.plist, which may cause permission denials or app crashes in some code editors.

Windows Setup

Update Visual Studio to the latest version for using C++ 20.

[!TIP] If you can't compile, try downloading the latest Windows SDK:

  1. Open Visual Studio Installer
  2. Select Modify
  3. Select Windows SDK

Linux Setup

Linux is not officially supported, but can be added through a non-endorsed federated plugin. See: gal_linux

💻 Usage

Save from Local

// Save Image (Supports two ways)
await Gal.putImage('$filePath');
await Gal.putImageBytes('$uint8List');

// Save Video
await Gal.putVideo('$filePath');

// Save to Album
await Gal.putImage('$filePath', album: '$album')
...

Download from Internet

flutter pub add dio
// Download Image
final imagePath = '${Directory.systemTemp.path}/image.jpg';
await Dio().download('$url',imagePath);
await Gal.putImage(imagePath);

// Download Video
final videoPath = '${Directory.systemTemp.path}/video.mp4';
await Dio().download('$url',videoPath);
await Gal.putVideo(videoPath);

Save from Camera

flutter pub add image_picker
// Capture and Save
final image = await ImagePicker.pickImage(source: ImageSource.camera);
await Gal.putImage(image.path);
flutter pub add camera
// Record and Save
...
final video = await controller.stopVideoRecording();
await Gal.putVideo(video.path);

Handle Permissions

// Check Access Permission
final hasAccess = await Gal.hasAccess();

// Request Access Permission
await Gal.requestAccess();

// ... for saving to album
final hasAccess = await Gal.hasAccess(toAlbum: true);
await Gal.requestAccess(toAlbum: true);

Handle Errors

// Save Image with try-catch
try {
  await Gal.putImage('$filePath');
} on GalException catch (e) {
  log(e.type.message);
}

// Exception Type
enum GalExceptionType {
  accessDenied,
  notEnoughSpace,
  notSupportedFormat,
  unexpected;

  String get message => switch (this) {
        accessDenied => 'Permission to access the gallery is denied.',
        notEnoughSpace => 'Not enough space for storage.',
        notSupportedFormat => 'Unsupported file format.',
        unexpected => 'An unexpected error has occurred.',
      };
}

📚 Documentation

If you write an article about Gal, let us know in the discussion and we'll post the URL in the wiki or readme 🤝

💚 Trusted by Major Projects

Although Gal has only been released for a short time, it's already trusted by major projects.

and more...

Changelog

2.3.3

  • Fix Windows build on latest MSVC by removing /await flag #324

2.3.2

  • Reduce package size by optimizing assets (.pubignore) #296
  • Fix Windows build by adding windowsapp library linking for WinRT support #284

2.3.1

  • Add Swift Package Manager support. #242
  • Add PrivacyInfo.xcprivacy for Apple's Privacy Manifests. #242

2.3.0

  • Add name parameter to putImageBytes. #205

2.2.3

  • Fix error when saving the same file name 32 times on Android. #199

2.2.2

  • Fix analytics issue

2.2.1

  • UPDATE: Gradle settings to latest #196

2.2.0

  • ADD: PlatformInterface #180
  • FIX: package download size 1MB to 0.5MB #181

2.1.4

  • FIX: package download size 6MB to 1MB #175

2.1.3

  • FIX: Compilation error on Windows in some environments #166

2.1.2

  • UPDATE: document comments #158
  • UPDATE: metadata for pub.dev #158

2.1.1

  • UPDATE: putImageBytes for Improving performance on windows #155
  • FIX: putImageBytes for saving .tiff on windows #154

2.1.0

  • ADD: windows support #148

2.0.0

  • ADD: macOS support #142
  • BREAKING CHANGE: flutter: '>=3.3.0' to flutter: '>=3.7.0' #142
  • BREAKING CHANGE: GalException.error to GalException.platformException #143
  • BREAKING CHANGE: Remove GalExceptionType.notHandle (had marked deprecated) #144

1.9.1

  • FIX: album option is not working on Android API 29 #130
  • UPDATE: Permission behavior in Android API 29 with album option #133

1.9.0

  • ADD: Support for AGP 8 #118

1.8.6

  • UPDATE: Keep file name when saving #115
  • UPDATE: README.md

1.8.5

  • UPDATE: putImageBytes in iOS to get metadata

1.8.4

  • FIX: file auto conversion #105

1.8.3

  • FIX: dart format

1.8.2

  • FIX: put- does not run with Future #96
  • FIX: put- with album and user selects 'selected photos' in permission dialog #95
  • ADD: requestAccess when called put- #97

1.8.1

  • REMOVE: plugin_platform_interface #84
  • FIX: example with toAlbum
  • UPDATE: example in readme
  • UPDATE: assets in example
  • UPDATE: GalException error messages

1.8.0

  • FEAT: Gal supports album option for saving medias. iOS needs additional permission settings, see latest README or wiki.

1.7.0

  • ADD: Support Android API 21-23.

1.6.3

  • FIX: Crashing on permission requests for other packages.

1.6.2

  • FIX: Returning false when permission granted by default when calling hasAccess(),requestAccess() in Android.
  • UPDATE: Include maxSdkVersion as a key to write in AndroidManifest. *It is not necessary, but it is recommended.

1.6.1

  • UPDATE: We have made a stronger typing. Gal,GalException,MethodChannelGal has @immutable now.
  • UPDATE: update README.

1.6.0

  • UPDATE: Significantly improved error handling for low iOS versions. As a result, GalExceptionType.notHandle is now @Deprecated and will be removed in the next major version.

1.5.0

  • FEAT: Add putImageBytes(). This allows saving image from memory.

1.4.1

  • UPDATE: update README.

1.4.0

  • UPDATE: Galis final now.
  • UPDATE: add export file.
  • UPDATE: add ios NOT_SUPPORTED_FORMAT condition.

1.3.6

  • UPDATE: add error info on throw.
  • UPDATE: clean up native codes.
  • UPDATE: update README.

1.3.5

  • UPDATE: fix example.
  • UPDATE: update README.

1.3.4

  • UPDATE: update code docs.
  • UPDATE: update README.

1.3.3

  • FIX: fix README

1.3.2

  • FIX: remove android:requestLegacyExternalStorage="true"

1.3.1

  • FIX: fix README
  • UPDATE: make gal constractor private

1.3.0

  • FEAT: Add permissionhandlings. Now you can use hasAccess(),requestAccess().

1.2.0

  • UPDATE: remove url_launcher and android_intent_plus

1.1.2

  • FIX: fix README

1.1.1

  • UPDATE: add examples

1.1.0

  • FEAT: add error handlings

1.0.7

  • UPDATE: transfer repo

1.0.6

  • UPDATE: update README

1.0.5

  • FIX: refactor

1.0.4

  • FIX: update README

1.0.3

  • FIX: update README

1.0.2

  • FIX: update README

1.0.1

  • FIX: update README

1.0.0

  • FEAT: saving image

0.0.5

  • UPDATE: update README

0.0.4

  • FIX: fix CHANGELOG

0.0.3

  • UPDATE: dartdoc comments

0.0.2

  • UPDATE: update description field of pubspec.yaml

0.0.1

  • Initial Release

Installing

export PUB_HOSTED_URL=https://pub.mirror.p-hatan.com
flutter pub add gal
pubspec.yaml
name: gal
description: Flutter plugin to save images/videos to photos gallery with permission handling
version: 2.3.3
homepage: https://pub.dev/packages/gal
repository: https://github.com/natsuk4ze/gal
documentation: https://github.com/natsuk4ze/gal/wiki
funding: 
 - https://github.com/sponsors/natsuk4ze

topics:
 - gallery
 - video
 - image
 - photos
 - util


environment:
  sdk: '>=3.0.0 <4.0.0'
  flutter: '>=3.7.0'

dependencies:
  flutter:
    sdk: flutter

dev_dependencies:
  flutter_lints: ">=4.0.0 <7.0.0"

flutter:
  plugin:
    platforms:
      android:
        package: studio.midoridesign.gal
        pluginClass: GalPlugin
      ios:
        pluginClass: GalPlugin
        sharedDarwinSource: true
      macos:
        pluginClass: GalPlugin
        sharedDarwinSource: true
      windows:
        pluginClass: GalPluginCApi

Version history

VersionPublishedArchiveSHA-256
0.0.1On demandDownloadd6feef7c…b8f13d
0.0.2On demandDownloade0113109…100f43
0.0.3On demandDownload0dd6a1c5…cde484
0.0.4On demandDownload1fa6f3e7…4f345a
0.0.5On demandDownload29f8e24f…d6bd42
1.0.0On demandDownloadfa05115e…2a264e
1.0.1On demandDownload881813ab…8b78be
1.0.2On demandDownload3fa1d26d…2f7041
1.0.3On demandDownloadb84bf57e…ba4e96
1.0.4On demandDownload82b81a54…40bdc4
1.0.5On demandDownload240e4b7c…325d60
1.0.6On demandDownloada976a34d…7c975b
1.0.7On demandDownload3ecf803d…1e3fce
1.1.0On demandDownload537491f2…214c54
1.1.1On demandDownload60d08dd6…05f39d
1.1.2On demandDownloadb73cd0e4…c18c6b
1.2.0On demandDownloadbb554e88…db7950
1.3.0On demandDownloadc061b732…a31e6c
1.3.1On demandDownload1944909d…064a9a
1.3.2On demandDownload7bf5e544…cf31ee
1.3.3On demandDownload1d38feba…7154de
1.3.4On demandDownload397c8c92…10f642
1.3.5On demandDownload504932eb…346c83
1.3.6On demandDownload39eba05d…e15664
1.4.0On demandDownload51d4e651…812b1d
1.4.1On demandDownloaddb5e6698…cdac5e
1.5.0On demandDownload4f37184d…f94b62
1.6.0On demandDownload216e3089…4f45ff
1.6.1On demandDownload2d2939e4…3efc06
1.6.2On demandDownload8113a611…4c7578
1.6.3On demandDownload44466667…99c49e
1.7.0On demandDownload49855345…6c9cf4
1.8.0On demandDownload5fb3ac26…32fb77
1.8.1On demandDownloadc57bc3be…9b8322
1.8.2On demandDownload9f852b03…4cbd7c
1.8.3On demandDownload13485cb0…7ab415
1.8.4On demandDownload7b5256b1…c31489
1.8.5On demandDownload5dc4a17c…bf164e
1.8.6On demandDownload612a2bb6…099020
1.9.0On demandDownloaddcb4c906…939c38
1.9.1On demandDownload1bdef587…c67d66
2.0.0On demandDownload370294ae…b065b0
2.1.0On demandDownload170af7a7…36bcff
2.1.1On demandDownload2132ff8c…1af82e
2.1.2On demandDownloadebc581be…444246
2.1.3On demandDownload571ef8a7…870d36
2.1.4On demandDownloade53ff864…e299f7
2.2.0On demandDownload88f8e870…be29e5
2.2.1On demandDownload0edbcf52…17b1e9
2.2.2On demandDownload03ee7c9f…b4dd37
2.2.3On demandDownloadd9a312c5…2ee631
2.3.0On demandDownload54c9b725…940977
2.3.1On demandDownload2771519c…a208e4
2.3.2On demandDownload969598f9…afdfee
2.3.3Cached · Upstream SHA-256 matchedDownloadf71e7984…380a77

Dependencies

flutter { "sdk": "flutter" }