Package selection guidance compiled from public package information, community data, and project usage.
The screenshot package enables runtime capture of any Flutter widget as an image across multiple platforms. It allows developers to programmatically take screenshots of widgets during app execution, useful for debugging, testing, or sharing visual content. The package supports Android, iOS, Web, macOS, Windows, and Linux, making it highly versatile. It integrates seamlessly with Flutter's rendering pipeline and provides a simple API to generate images from widget trees. Ideal for apps requiring dynamic image generation or visual feedback.
Use cases
Debugging UI issues
Generating shareable images
Automated testing
Visual documentation
App tutorials
Preview features
Key features
Runtime widget screenshot capture
Cross-platform support
Simple API integration
High-quality image output
Supports all major platforms
No external dependencies
Suitable for
Developers needing dynamic screenshots
Testing and QA teams
Apps with visual sharing features
Educational or tutorial apps
UI prototyping tools
Debugging complex layouts
Considerations
Performance impact on large widgets
Memory usage for high-resolution images
Requires proper permissions on mobile platforms
Not suitable for real-time video capture
Limited to static widget snapshots
May require platform-specific configuration
Original README
Original README snapshot from the linked source repository. Visit the repository for the latest content.
A simple package to capture widgets as Images. Now you can also capture the widgets that are not rendered on the screen!
You can capture a long Invisible widgets by using captureFromLongWidget function.
var randomItemCount = Random().nextInt(100);
////// Step 1: Create Long widget using Column.///var myLongWidget = Builder(builder: (context) {
returnContainer(
padding: constEdgeInsets.all(30.0),
decoration: BoxDecoration(
border:
Border.all(color: Colors.blueAccent, width: 5.0),
color: Colors.redAccent,
),
////// Note: Do not use Scrolling widget, instead place your children in Column. /// /// Do not use widgets like 'Expanded','Flexible',or 'Spacer'///
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
for (int i = 0; i < randomItemCount; i++)
Text("Tile Index $i"),
],
));
});
////// Step 2: /// Use `captureFromLongWidget` function for taking screenshot.///
screenshotController
.captureFromLongWidget(
InheritedTheme.captureAll(
context,
Material(
child: myLongWidget,
),
),
delay: Duration(milliseconds: 100),
context: context,
////// Additionally you can define constraint for your image.////// constraints: BoxConstraints(/// maxHeight: 1000,/// maxWidth: 1000,/// )
)
.then((capturedImage) {
// Handle captured image
});
Saving images to Specific Location
For this you can use captureAndSave method by passing directory location. By default, the captured image will be saved to Application Directory. Custom paths can be set using path parameter. Refer path_provider
Note
Method captureAndSave is not supported for web.
final directory = (await getApplicationDocumentsDirectory ()).path; //from path_provide packageString fileName = DateTime.now().microsecondsSinceEpoch;
path = '$directory';
screenshotController.captureAndSave(
path //set path where screenshot will be saved
fileName:fileName
);
Saving images to Gallery
If you want to save captured image to Gallery, Please use https://github.com/hui-z/image_gallery_saver
Example app uses the same to save screenshots to gallery.
Sharing Captured Images
await _screenshotController.capture(delay: constDuration(milliseconds: 10)).then((Uint8List image) async {
if (image != null) {
final directory = awaitgetApplicationDocumentsDirectory();
final imagePath = awaitFile('${directory.path}/image.png').create();
await imagePath.writeAsBytes(image);
/// Share PluginawaitShare.shareFiles([imagePath.path]);
}
});
Note:
Captured image may look pixelated. You can overcome this issue by setting value for pixelRatio
The pixelRatio describes the scale between the logical pixels and the size of the output image. It is independent of the window.devicePixelRatio for the device, so specifying 1.0 (the default) will give you a 1:1 mapping between logical pixels and the output pixels in the image.