alhilali_device_preview_screenshot
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:
- Open the Device Preview toolbar or side panel.
- Open the screenshot/export section.
- Click Export transparent PNG to export the currently selected device.
- If
multipleScreenshots: trueis enabled, click Export all devices to export every configured device.
If you cannot see the option:
- Make sure
DevicePreviewScreenshot()is insideDevicePreview.tools. - Make sure you kept
...DevicePreview.defaultToolsif you still want the default Device Preview controls. - Make sure
DevicePreviewis enabled. If you useenabled: !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.