Flutter- Screenshot Package - GeeksforGeeks

12 Jan, 2022
Flutter is a popular framework by Google which is growing fast with its growing community. The Flutter has created a buzz through its libraries, making the development fast-paced.
Nowadays, everyone loves to take screenshots. If your application involves the use of screenshots, Flutter got a package for it. Not only for this purpose, but it is very helpful in the testing and debugging process. The fast-changing data screens can be captured through screenshots, and doing this manually is a boring task as well as time-wasting. The screenshot package automates the process of capturing the widgets you want to capture and storing them somewhere.  If you want your user to capture only certain widgets of the screen, not an entire screen, this package is here to help you. In this article, we will implement a screenshot package in Flutter.
Follow the article to see how to do screenshot work in Flutter.
Step 1: Add the following dependency in your pubspec.yaml file.
Add the given dependency in pubspec.yaml file.
Dart
dependencies:  screenshot: ^1.2.3
 Now click on the pub get to configure it. Or add dependency directly to the pubspec.yaml from the terminal by writing the below code in the terminal.
flutter pub add screenshot
Step 2: Import the library. 
Dart
import 'package:screenshot/screenshot.dart';
 Step 3: Navigate to main.dart.
First, move to the main.dart and modify the main function. When you create a Flutter app, some lines of code are already written for you. We are going to keep it. Remove the stateless widget MyHomePage from the code, and keep only the below-shown code. Then give our first screen of the app in the home: HomePage(). 
Dart
import 'package:flutter/material.dart';import 'home.dart'; void main() {  runApp(const MyApp());} class MyApp extends StatelessWidget {  const MyApp({Key? key}) : super(key: key);   // This widget is the root of your application.  @override  Widget build(BuildContext context) {    return MaterialApp(      title: 'Flutter Demo',      theme: ThemeData(                 primarySwatch: Colors.green,      ),      home: HomePage(),    );  }}
 Step 4: Declare StatefulWidget() for HomePage() class
Create another dart file home.dart where we will create a stateful HomePage() class. In that HomePage() class, we have given screenshotController. After that, we have declared Scaffold() in which we have declared appbar that consists of the title of the app – “Screenshot Demo App”. In the body section, we have declared the Screenshot widget that takes screenshotController as a parameter wrapped with the center widget. 
We have created two ElevatedButton, one shows the decreasing timer and the other is an increasing timer. We can take a screenshot of both the buttons by pressing another button that shows Capture above Widget. This will show the captured widget on a different screen. Remember, we need to wrap all the widgets inside the Screenshot widget whose screenshot you want. We have wrapped both the timers as well as their respective texts inside the Screenside widget. At the respective particular values, both timers will stop, and by clicking the refresh button their values will be reset. 
Sometimes, it takes time to load the widgets on the screen, and they are invisible until they are not on the screen. But with this library, we can even capture them. To show that, we have created an invisible widget, that is captured when another button that shows Capture An Invisible Widget is pressed. This will show the invisible widget on another screen.
Dart
import 'dart:async';import 'dart:typed_data';import 'package:flutter/material.dart';import 'package:screenshot/screenshot.dart'; class HomePage extends StatefulWidget {  @override  _HomePageState createState() => _HomePageState();} class _HomePageState extends State<HomePage> {     // Create an instance of ScreenshotController  ScreenshotController screenshotController = ScreenshotController();   @override  void initState() {    super.initState();  }   // create a variable of type Timer  late Timer _timer;  int _start = 0;  int _startTwo = 61;   // function to increment the timer until  // 61 and set the state  void increasingStartTimer() {    const oneSec = const Duration(seconds: 1);    _timer = new Timer.periodic(      oneSec,      (Timer timer) => setState(        () {          if (_start > 60) {            timer.cancel();          } else {            _start = _start + 1;          }        },      ),    );  }   // function to decrease the timer  // until 1 and set the state  void decreasingStartTimer() {    const oneSec = const Duration(seconds: 1);    _timer = new Timer.periodic(      oneSec,      (Timer timer) => setState(        () {          if (_startTwo < 0) {            timer.cancel();          } else {            _startTwo = _startTwo - 1;          }        },      ),    );  }   @override  void dispose() {    _timer.cancel();    super.dispose();  }   @override  Widget build(BuildContext context) {    return Scaffold(      appBar: AppBar(        title: Text("GeeksForGeeks"),        centerTitle: true,      ),      body: Center(        child: Column(          children: [            SizedBox(height: 30),            Screenshot(              controller: screenshotController,              child: Column(                children: [                  Text("Decreasing Timer : "),                  SizedBox(                    height: 10,                  ),                  Container(                      padding: const EdgeInsets.all(30.0),                      decoration: BoxDecoration(                        border:                            Border.all(color: Colors.blueAccent, width: 5.0),                        color: Colors.amberAccent,                      ),                      child: Text(_startTwo.toString())),                  SizedBox(                    height: 25,                  ),                  Text("Increasing Timer : "),                  SizedBox(                    height: 10,                  ),                  Container(                      padding: const EdgeInsets.all(30.0),                      decoration: BoxDecoration(                        border:                            Border.all(color: Colors.blueAccent,                                       width: 5.0),                        color: Colors.amberAccent,                      ),                      child: Text("$_start")),                ],              ),            ),            ElevatedButton(              onPressed: () {                                 // invoking both functions for timer to start                increasingStartTimer();                decreasingStartTimer();              },              child: Text("start"),            ),            ElevatedButton(                onPressed: () {                  setState(() {                    _start = 0;                    _startTwo = 61;                  });                },                child: Text("Refresh")),            ElevatedButton(              child: Text(                'Capture Above Widget',              ),              onPressed: () {                                 // invoking capture on                // screenshotController                screenshotController                    .capture(delay: Duration(milliseconds: 10))                    .then((capturedImage) async {                                         // showing the captured widget                  // through ShowCapturedWidget                  ShowCapturedWidget(context,                                     capturedImage!);                }).catchError((onError) {                  print(onError);                });              },            ),            ElevatedButton(              child: Text(                'Capture An Invisible Widget',              ),              onPressed: () {                var container = Container(                    padding: const EdgeInsets.all(30.0),                    decoration: BoxDecoration(                      border: Border.all(color: Colors.blueAccent,                                         width: 5.0),                      color: Colors.pink,                    ),                    child: Text(                      "This is an invisible widget",                      style: Theme.of(context).textTheme.headline6,                    ));                                 // capturing all the widgets                // that are invisible                screenshotController                    .captureFromWidget(                        InheritedTheme.captureAll(                            context, Material(child: container)),                        delay: Duration(seconds: 1))                    .then((capturedImage) {                                         // showing the captured invisible widgets                  ShowCapturedWidget(context, capturedImage);                });              },            ),          ],        ),      ),    );  }   // function to show captured widget  Future<dynamic> ShowCapturedWidget(      BuildContext context, Uint8List capturedImage) {    return showDialog(      useSafeArea: false,      context: context,      builder: (context) => Scaffold(        appBar: AppBar(          title: Text("Captured widget screenshot"),        ),        body: Center(            child: capturedImage != null                ? Image.memory(capturedImage)                : Container()),      ),    );  }}
The captured screenshots: 
To save screenshots in the gallery, we need to write additional code for them in the previously shown code. We will be using a package – image_gallery_saver for this purpose. Add below dependency in pubspec.yaml file.
Dart
dependencies:     image_gallery_saver: '^1.7.1'
 Now, run pub get to configure it, and we need to import the library in our home.dart file.  
Dart
import 'package:image_gallery_saver/image_gallery_saver.dart';
 Now, we need to create a function to which we will pass captured images to save to the Gallery. 
Dart
_saved(Uint8List image) async {   final result = await ImageGallerySaver.saveImage(image);   print("File Saved to Gallery"); }
Here, we created an asynchronous function that takes Uint8List type data as input. We can save images as files or bytes but we need to convert them to a specific type. Since the screenshots captured are in bytes format, we are using the saveImage function to save the screenshot. Now, we need to call the function, we will be calling this function each time we capture a screenshot, both of a visible widget and an invisible widget. See the complete code of the home.dart below.
Complete Source Code:
Dart
import 'dart:async';import 'dart:typed_data';import 'package:image_gallery_saver/image_gallery_saver.dart';import 'package:flutter/material.dart';import 'package:screenshot/screenshot.dart'; class HomePage extends StatefulWidget {  @override  _HomePageState createState() => _HomePageState();} class _HomePageState extends State<HomePage> {     // Create an instance of ScreenshotController  ScreenshotController screenshotController = ScreenshotController();   @override  void initState() {    super.initState();  }      late Timer _timer;  int _start = 0;  int _startTwo = 61;   void increasingStartTimer() {    const oneSec = const Duration(seconds: 1);    _timer = new Timer.periodic(      oneSec,      (Timer timer) => setState(        () {          if (_start > 60) {            timer.cancel();          } else {            _start = _start + 1;          }        },      ),    );  }   void decreasingStartTimer() {    const oneSec = const Duration(seconds: 1);    _timer = new Timer.periodic(      oneSec,      (Timer timer) => setState(        () {          if (_startTwo < 0) {            timer.cancel();          } else {            _startTwo = _startTwo - 1;          }        },      ),    );  }   @override  void dispose() {    _timer.cancel();    super.dispose();  }   @override  Widget build(BuildContext context) {    return Scaffold(      appBar: AppBar(        title: Text("Screenshot Demo App"),      ),      body: Center(        child: Column(          children: [            SizedBox(height: 30),            Screenshot(              controller: screenshotController,              child: Column(                children: [                  Text("Decreasing Timer : "),                  SizedBox(                    height: 10,                  ),                  Container(                      padding: const EdgeInsets.all(30.0),                      decoration: BoxDecoration(                        border:                            Border.all(color: Colors.blueAccent, width: 5.0),                        color: Colors.amberAccent,                      ),                      child: Text(_startTwo.toString())),                  SizedBox(                    height: 25,                  ),                  Text("Increasing Timer : "),                  SizedBox(                    height: 10,                  ),                  Container(                      padding: const EdgeInsets.all(30.0),                      decoration: BoxDecoration(                        border:                            Border.all(color: Colors.blueAccent, width: 5.0),                        color: Colors.amberAccent,                      ),                      child: Text("$_start")),                ],              ),            ),            ElevatedButton(              onPressed: () {                increasingStartTimer();                decreasingStartTimer();              },              child: Text("start"),            ),            ElevatedButton(                onPressed: () {                  setState(() {                    _start = 0;                    _startTwo = 61;                  });                },                child: Text("Refresh")),            ElevatedButton(              child: Text(                'Capture Above Widget',              ),              onPressed: () {                screenshotController                    .capture(delay: Duration(milliseconds: 10))                    .then((capturedImage) async {                  ShowCapturedWidget(context, capturedImage!);                  _saved(capturedImage);                }).catchError((onError) {                  print(onError);                });              },            ),            ElevatedButton(              child: Text(                'Capture An Invisible Widget',              ),              onPressed: () {                var container = Container(                    padding: const EdgeInsets.all(30.0),                    decoration: BoxDecoration(                      border: Border.all(color: Colors.blueAccent,                                         width: 5.0),                      color: Colors.pink,                    ),                    child: Text(                      "This is an invisible widget",                      style: Theme.of(context).textTheme.headline6,                    ));                 screenshotController                    .captureFromWidget(                        InheritedTheme.captureAll(                            context, Material(child: container)),                        delay: Duration(seconds: 1))                    .then((capturedImage) {                  ShowCapturedWidget(context, capturedImage);                  _saved(capturedImage);                });              },            ),          ],        ),      ),    );  }   Future<dynamic> ShowCapturedWidget(      BuildContext context, Uint8List capturedImage) {    return showDialog(      useSafeArea: false,      context: context,      builder: (context) => Scaffold(        appBar: AppBar(          title: Text("Captured widget screenshot"),        ),        body: Center(            child: capturedImage != null                ? Image.memory(capturedImage)                : Container()),      ),    );  }   _saved(image) async {    final result = await ImageGallerySaver.saveImage(image);    print("File Saved to Gallery");  } }
Output:
sagartomar9927
simmytarika5
Flutter
Android
Dart
Flutter
Android
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Flutter - Custom Bottom Navigation Bar
How to Read Data from SQLite Database in Android?
Android Listview in Java with Example
Retrofit with Kotlin Coroutine in Android
How to Change the Background Color After Clicking the Button in Android?
Flutter - DropDownButton Widget
Listview.builder in Flutter
Flutter - Asset Image
Flutter - Custom Bottom Navigation Bar
Splash Screen in Flutter