alhilali_device_preview_screenshot

pub package

Screenshot export plugin for alhilali_device_preview.

It adds a clear action to Device Preview that exports the currently previewed device as a high-resolution transparent PNG.

What Gets Exported

The PNG includes:

  • device frame
  • screen content
  • bezels
  • notches
  • dynamic islands
  • visible device decorations

The PNG does not include:

  • editor background
  • app/workspace background outside the device
  • Device Preview toolbar
  • overlays outside the device preview

This makes the output suitable for App Store, Play Store, landing pages, and marketing screenshots.

Install

dependencies:
  alhilali_device_preview: ^1.3.3
  alhilali_device_preview_screenshot: ^1.0.1

Basic Usage

Installing this package alone is not enough to show the screenshot button. You must register the plugin in the tools list of DevicePreview.

import 'package:alhilali_device_preview/alhilali_device_preview.dart';
import 'package:alhilali_device_preview_screenshot/alhilali_device_preview_screenshot.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';

void main() {
  runApp(
    DevicePreview(
      enabled: !kReleaseMode,
      tools: const [
        ...DevicePreview.defaultTools,
        DevicePreviewScreenshot(),
      ],
      builder: (context) => const MyApp(),
    ),
  );
}

Open the Device Preview toolbar, then click Export transparent PNG.

Where Is The Button?

After adding the plugin, run your app in debug mode:

flutter run

Then:

  1. Open the Device Preview toolbar or side panel.
  2. Open the screenshot/export section.
  3. Click Export transparent PNG to export the currently selected device.
  4. If multipleScreenshots: true is enabled, click Export all devices to export every configured device.

If you cannot see the option:

  • Make sure DevicePreviewScreenshot() is inside DevicePreview.tools.
  • Make sure you kept ...DevicePreview.defaultTools if you still want the default Device Preview controls.
  • Make sure DevicePreview is enabled. If you use enabled: !kReleaseMode, the UI appears only outside release builds.
  • Restart the app after changing dependencies or imports.

High-Resolution Export

Use pixelRatio to create larger screenshots:

DevicePreviewScreenshot(
  pixelRatio: 4,
)

If pixelRatio is not set, the plugin uses the selected preview device pixel ratio.

Save To A Local Directory

Use screenshotAsFiles when your app runs on desktop or in an environment where the target directory is writable.

import 'dart:io';

import 'package:alhilali_device_preview_screenshot/alhilali_device_preview_screenshot.dart';

final outputDirectory = Directory('screenshots')..createSync(recursive: true);

DevicePreviewScreenshot(
  pixelRatio: 4,
  onScreenshot: screenshotAsFiles(outputDirectory),
)

Output file names use the selected device identifier and a timestamp.

Save To Android Pictures With media_store_plus

On Android, app-private directories are not easy for users to access. To save PNG files in a public folder such as Pictures/DevicePreviewExports, use media_store_plus.

Add dependencies:

dependencies:
  alhilali_device_preview: ^1.3.3
  alhilali_device_preview_screenshot: ^1.0.1
  media_store_plus: ^0.1.3
  path_provider: ^2.1.5

Add Android permissions in android/app/src/main/AndroidManifest.xml:

<manifest xmlns:android="http://schemas.android.com/apk/res/android">
    <uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
    <uses-permission
        android:name="android.permission.READ_EXTERNAL_STORAGE"
        android:maxSdkVersion="32" />
    <uses-permission
        android:name="android.permission.WRITE_EXTERNAL_STORAGE"
        android:maxSdkVersion="29" />

    <application
        android:requestLegacyExternalStorage="true"
        ...>
    </application>
</manifest>

Create a custom screenshot processor:

import 'dart:io';
import 'dart:ui';

import 'package:alhilali_device_preview/alhilali_device_preview.dart';
import 'package:alhilali_device_preview_screenshot/alhilali_device_preview_screenshot.dart';
import 'package:media_store_plus/media_store_plus.dart';
import 'package:path_provider/path_provider.dart';

const androidExportFolder = 'DevicePreviewExports';
final mediaStore = MediaStore();

Future<void> initializeScreenshotExport() async {
  if (Platform.isAndroid) {
    await MediaStore.ensureInitialized();
    MediaStore.appFolder = androidExportFolder;
  }
}

ScreenshotProcessor saveScreenshotToAndroidPictures() {
  return (context, screenshot) async {
    if (!Platform.isAndroid) {
      final directory = Directory('screenshots')..createSync(recursive: true);
      await screenshotAsFiles(directory)(context, screenshot);
      return;
    }

    if (screenshot.format != ImageByteFormat.png) {
      throw UnsupportedError('Only PNG screenshots can be saved to MediaStore.');
    }

    final tempDirectory = await getTemporaryDirectory();
    final fileName =
        '${screenshot.device.identifier}_${DateTime.now().millisecondsSinceEpoch}.png';
    final tempFile = File('${tempDirectory.path}${Platform.pathSeparator}$fileName');

    await tempFile.writeAsBytes(screenshot.bytes, flush: true);

    await mediaStore.saveFile(
      tempFilePath: tempFile.path,
      dirType: DirType.photo,
      dirName: DirName.pictures,
    );
  };
}

Use it in main:

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await initializeScreenshotExport();

  runApp(
    DevicePreview(
      enabled: !kReleaseMode,
      tools: [
        ...DevicePreview.defaultTools,
        DevicePreviewScreenshot(
          pixelRatio: 4,
          onScreenshot: saveScreenshotToAndroidPictures(),
        ),
      ],
      builder: (context) => const MyApp(),
    ),
  );
}

The screenshots will be saved in:

Pictures/DevicePreviewExports

Export All Devices

Enable batch export:

DevicePreviewScreenshot(
  pixelRatio: 4,
  multipleScreenshots: true,
)

Then use Export all devices from the screenshot section.

Custom Processing

You can upload screenshots, save them to cloud storage, attach them to test reports, or process them in memory by providing your own ScreenshotProcessor.

DevicePreviewScreenshot(
  onScreenshot: (context, screenshot) async {
    final bytes = screenshot.bytes;
    final device = screenshot.device;
    // Save, upload, or transform bytes here.
  },
)

Complete Example

See:

examples/transparent_png_export_example

The example demonstrates high-resolution transparent PNG export and Android public gallery storage.

License

MIT.