Programmatically take screenshot in flutter

Hi Guys, Welcome to Proto Coders Point, In this flutter article will learn how can we programmatically take a screenshot in flutter. Add this feature into your flutter app so that users can take screenshot of the app screen when they want to, just by clicking a button.

Let’s get started – Taking Screenshot in flutter app

To capture our app screen will make use of flutter inBuilt widget i.e. RepaintBoundry.

Using RepaintBoundry widget

RePaintBoundry widget in flutter will capture the view of the child it wrapped with, For Example: if you wrap RepaintBoundry with Container Widget then your app will only capture that widget, suppose if you want to take screenshot of complete app screen then you need to wrap RePaintBoundry to Scaffold widget as done in below complete code.
Then attach a GlobalKey to RepaintBoundry.
Next, by using GlobalKey currentContext we can use .findRenderObject() method helps us in finding current render object.
Next, will use toImage() method to convert render object to image.
then, will convert image into byteData which will again get converted to asUint8List().
Next, will use the Uint8List format to save the screenshot by using ImageGallerySaver package.

Below method take screenshowt and save it.

void _CaptureScreenShot() async{
    //get paint bound of your app screen or the widget which is wrapped with RepaintBoundary.
    RenderRepaintBoundary bound = _key.currentContext!.findRenderObject() as RenderRepaintBoundary;

    if(bound.debugNeedsPaint){
      Timer(Duration(seconds: 1),()=>_CaptureScreenShot());
      return null;
    }

    ui.Image image = await bound.toImage();
    ByteData? byteData = await image.toByteData(format: ui.ImageByteFormat.png);

    // this will save image screenshot in gallery
    if(byteData != null ){
      Uint8List pngBytes = byteData.buffer.asUint8List();
      final resultsave = await ImageGallerySaver.saveImage(Uint8List.fromList(pngBytes),quality: 90,name: 'screenshot-${DateTime.now()}.png');
      print(resultsave);
    }
  }

Programmatically take screenshot in flutter

Complete Code implement to take screenshot in flutter in step

Step 1: Add ImageGallerySaver

In your flutter project, open pubspec.yaml file and under dependencies section add the image gallery saver flutter library.

dependencies:
  image_gallery_saver: '^1.7.1'

Step 2: Add Permission to save image in galery

Android External Storage permission

Open manifest file, and under application tag add:

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

iOS Photo Library usage permission

Navigate to <project>/ios/Runner/info.plist, then between <dict></dict> add below lines

<key>NSPhotoLibraryAddUsageDescription</key>
<string>This app need access to your gallery to save screenshots</string>


Step 3: Complete Code

Refer comment in code for better understanding

main.dart

import 'dart:async';
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'dart:ui' as ui;
import 'package:flutter/services.dart';
import 'package:image_gallery_saver/image_gallery_saver.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.blue,
      ),
      home: const MyHomepage(),
    );
  }
}

class MyHomepage extends StatefulWidget {
  const MyHomepage({Key? key}) : super(key: key);

  @override
  State<MyHomepage> createState() => _MyHomepageState();
}

class _MyHomepageState extends State<MyHomepage> {
  final GlobalKey _key = GlobalKey();

  void _CaptureScreenShot() async{
    //get paint bound of your app screen or the widget which is wrapped with RepaintBoundary.
    RenderRepaintBoundary bound = _key.currentContext!.findRenderObject() as RenderRepaintBoundary;

    if(bound.debugNeedsPaint){
      Timer(Duration(seconds: 1),()=>_CaptureScreenShot());
      return null;
    }

    ui.Image image = await bound.toImage();
    ByteData? byteData = await image.toByteData(format: ui.ImageByteFormat.png);

    // this will save image screenshot in gallery
    if(byteData != null ){
      Uint8List pngBytes = byteData.buffer.asUint8List();
      final resultsave = await ImageGallerySaver.saveImage(Uint8List.fromList(pngBytes),quality: 90,name: 'screenshot-${DateTime.now()}.png');
      print(resultsave);
    }
  }

  @override
  Widget build(BuildContext context) {
    //Here i have wrapped whole app screen scaffold widget, to take full screenshot
    return RepaintBoundary(
      key: _key,
      child: Scaffold(
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Container(color:Colors.blue,width: 220,height: 220,),
              SizedBox(height: 25,),
              ElevatedButton(onPressed: (){
                _CaptureScreenShot(); // Method called to take screenshot on wrapped widget and save it.
              }, child: Text("Capture & Save"))
            ],
          )
        ),
      ),
    );
  }
}

Video Tutorial