flutter_native_gallery 0.2.2 copy "flutter_native_gallery: ^0.2.2" to clipboard
flutter_native_gallery: ^0.2.2 copied to clipboard

Native photo and video picker with image optimization and media metadata.

flutter_native_gallery #

A native photo and video gallery picker for Flutter with album browsing, pagination, ordered multiple selection, Live Photo detection, image optimization, and media metadata extraction.

Features #

  • Requests native photo library permissions.
  • Reads albums, photos, videos, and available native metadata.
  • Presents a responsive, draggable gallery bottom sheet.
  • Opens album selection in a full-height page with safe-area handling.
  • Loads large galleries incrementally.
  • Supports image-only, video-only, or combined media requests.
  • Preserves the order of multiple selections.
  • Limits selection to 30 items by default with a configurable maximum.
  • Detects Live Photos on supported Apple platforms.
  • Shows video duration and Live Photo indicators.
  • Provides a configurable HD selection control.
  • Adapts the HD control to light, dark, and custom application color schemes.
  • Optimizes non-HD images with configurable quality and dimensions.
  • Preserves EXIF data when supported.
  • Extracts dimensions, dates, duration, MIME type, location, camera, exposure, favorite state, Live Photo state, and serializable EXIF values.
  • Exposes configurable labels for localization.
  • Provides both a ready-to-use picker and a lower-level gallery controller.

Platform Requirements #

iOS #

Photo library access requires NSPhotoLibraryUsageDescription in Info.plist:

<key>NSPhotoLibraryUsageDescription</key>
<string>Photo library access is used to select media.</string>

NSPhotoLibraryAddUsageDescription is only required when selected media can also be written back to the library:

<key>NSPhotoLibraryAddUsageDescription</key>
<string>Photo library access is used to save media.</string>

Android #

Gallery access uses the media permissions supported by each Android version:

<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
<uses-permission android:name="android.permission.READ_MEDIA_VISUAL_USER_SELECTED" />
<uses-permission android:name="android.permission.ACCESS_MEDIA_LOCATION" />
<uses-permission
    android:name="android.permission.READ_EXTERNAL_STORAGE"
    android:maxSdkVersion="32" />

ACCESS_MEDIA_LOCATION allows coordinates to be read when they are present and the operating system grants access.

Basic Usage #

import 'dart:io';
import 'dart:typed_data';

import 'package:flutter_native_gallery/flutter_native_gallery.dart';

Open the picker and receive the selected assets in selection order:

final List<FlutterNativeGalleryAsset>? selectedAssets =
    await FlutterNativeGalleryPicker.show(
      context,
      config: const FlutterNativeGalleryPickerConfig(
        title: 'Recents',
        albumPickerTitle: 'Select an album',
        cancelLabel: 'Cancel',
        highQualityLabel: 'HD',
        highQualityTooltip: 'High quality',
        sendLabel: 'Select',
        requestType: FlutterNativeGalleryRequestType.imagesAndVideos,
        maxSelection: 30,
        showHighQualityToggle: true,
        highQualityInitiallySelected: false,
      ),
    );

A null result means the picker was dismissed. An empty gallery, denied permission, and limited-library access are handled by the picker UI.

Export Selected Media #

Resolve an asset to a file together with its normalized metadata:

for (final FlutterNativeGalleryAsset asset
    in selectedAssets ?? const <FlutterNativeGalleryAsset>[]) {
  final FlutterNativeGalleryAssetExport? exported = await asset.export();
  if (exported == null) continue;

  final File file = exported.file;
  final Map<String, dynamic> metadata = exported.toJson();
}

Videos and HD images use their original file. Non-HD images use the default 1920 x 1920 bounds at quality 82. An original file is retained when optimization would produce a larger result.

A Live Photo is a paired still image and motion resource. The single-file export contains the still image only, so its serialized metadata reports isLivePhoto: false and preserves the native source state as originalIsLivePhoto: true. This prevents consumers from treating a static JPEG or HEIF export as playable Live Photo media.

Customize non-HD image export with FlutterNativeGalleryImageExportOptions:

final FlutterNativeGalleryAssetExport? exported = await asset.export(
  imageOptions: const FlutterNativeGalleryImageExportOptions(
    quality: 76,
    maxWidth: 1600,
    maxHeight: 1600,
    format: FlutterNativeGalleryImageFormat.automatic,
    preserveExif: true,
    useOriginalWhenOptimizedFileIsLarger: true,
  ),
);

The highQuality argument overrides the value selected in the picker for an individual export:

final FlutterNativeGalleryAssetExport? original = await asset.export(
  highQuality: true,
);

Asset Metadata #

Read metadata without exporting or optimizing the file:

final FlutterNativeGalleryAssetMetadata metadata = await asset.metadata();

final bool hasCoordinates = metadata.hasCoordinates;
final String? device = metadata.device;
final String? format = metadata.format;
final Map<String, dynamic> json = metadata.toJson();

Metadata is best effort. Values unavailable from the operating system or source file remain null or are omitted from toJson().

Available metadata includes:

Category Values
Identity Asset id, file name, media type, and relative path.
Media Width, height, aspect ratio, duration, MIME type, format, and file size.
Dates Capture, creation, and modification dates.
Native state Orientation, subtype, favorite, trashed, and Live Photo state.
Location Latitude, longitude, and altitude when available.
Camera Make, model, lens, software, color space, and exposure values.
EXIF Serializable metadata entries exposed by the source file.

Asset API #

Each FlutterNativeGalleryAsset provides:

Member Description
id Native asset identifier.
title Native title or asset id fallback.
type Image, video, audio, or other.
width / height Oriented media dimensions.
aspectRatio Width-to-height ratio when dimensions are valid.
duration Video duration.
createdAt / modifiedAt Native asset dates when available.
mimeType Native MIME type when available.
isLivePhoto Live Photo state on supported Apple platforms.
highQualitySelected HD choice captured when the selection is returned.
file() Resolves the original or an optimized image file.
export() Resolves a file and its normalized metadata.
metadata() Reads metadata without requiring export.
thumbnail() Returns thumbnail bytes at the requested size and quality.

Request thumbnail bytes directly:

final Uint8List? thumbnail = await asset.thumbnail(
  width: 320,
  height: 320,
  quality: 80,
);

Picker Configuration #

FlutterNativeGalleryPickerConfig controls selection, presentation, and every visible label.

Option Default Description
controller null Optional controller used for permissions and gallery access.
requestType imagesAndVideos Loads images, videos, or both.
maxSelection 30 Maximum ordered selection count.
pageSize 80 Number of assets requested per page.
initialHeightFactor 0.58 Initial picker height.
minHeightFactor 0.34 Minimum drag extent before dismissal.
maxHeightFactor 0.96 Maximum expanded height.
showHighQualityToggle true Shows the HD control.
highQualityInitiallySelected false Initial HD state.
title Select attachments Picker title when no album name is available.
albumPickerTitle Select an album Album selection title.
cancelLabel Cancel Close action accessibility label.
highQualityLabel HD Visible quality label.
highQualityTooltip High quality Quality control accessibility label.
sendLabel Send Selection confirmation label.
recentsLabel Recents Recent-media fallback label.
emptyLabel No media found Empty gallery message.
permissionTitle Gallery access needed Permission state title.
permissionMessage Allow photo library access to choose media. Permission state message.
openSettingsLabel Open settings Settings action label.
limitedAccessLabel Manage selected photos Limited-library action label.

Controller API #

FlutterNativeGalleryController exposes gallery access without the picker UI:

const FlutterNativeGalleryController controller =
    FlutterNativeGalleryController();

final FlutterNativeGalleryPermissionStatus permission =
    await controller.requestPermission();

if (permission.canReadGallery) {
  final List<FlutterNativeGalleryAlbum> albums = await controller.albums();
}

Albums expose their native count, cover, and paginated assets. The controller also provides limited-library management, settings access, and cache clearing.

Platform Behavior #

Live Photo detection uses the native asset subtype available on iOS and macOS. Android does not expose the same subtype, so isLivePhoto remains false. Detection describes the native library asset; it does not imply that a single-file export contains the paired motion resource.

Limited photo access can restrict albums, files, and metadata. Coordinates and EXIF values can also be absent even when permission is granted.

License #

MIT License. See LICENSE.

1
likes
150
points
241
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

Native photo and video picker with image optimization and media metadata.

Repository (GitHub)
View/report issues

Topics

#gallery #media #picker #photos #videos

License

MIT (license)

Dependencies

exif_reader, flutter, flutter_image_compress, path, path_provider, photo_manager

More

Packages that depend on flutter_native_gallery