48

I need to take a screenshot of the current screen or widget and I need to write it into a file.

4 Answers 4

44

I tried and found the solution,

import 'package:flutter/material.dart';
import 'dart:async';
import 'dart:ui' as ui;
import 'package:flutter/rendering.dart';
import 'package:path_provider/path_provider.dart';
import 'dart:io';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({super.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(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});
  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  static GlobalKey previewContainer = GlobalKey();
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {

    return RepaintBoundary(
        key: previewContainer,
      child: Scaffold(
      appBar: AppBar(

        title: Text(widget.title),
      ),
      body: Center(
        child: Column(

          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            const Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headlineMedium,
            ),
            ElevatedButton(
                onPressed: takeScreenShot,
              child: const Text('Take a Screenshot'),
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: const Icon(Icons.add),
      ),
    )
    );
  }
  Future<void> takeScreenShot() async{
    final boundary = previewContainer.currentContext!.findRenderObject() as RenderRepaintBoundary;
    final image = await boundary.toImage();
    final directory = (await getApplicationDocumentsDirectory()).path;
    final byteData = await image.toByteData(format: ui.ImageByteFormat.png);
    final pngBytes = byteData?.buffer.asUint8List();
    final imgFile =File('$directory/screenshot.png');
    imgFile.writeAsBytes(pngBytes!);
  }
}

Finally check your application directory You will find screenshot.png !!

And finally got this output

Sign up to request clarification or add additional context in comments.

8 Comments

I am using this code but not take a full-screen screenshot
@mr.hir me too. I've checked this github.com/flutter/flutter/issues/17687 but the bug still exists.
image quality is bad. Is there anyway to control the quality of the screenshot?
Increasing the pixel ratio should improve the quality of the output image. ui.Image image = await boundary.toImage(pixelRatio: 2.0);
Is their any way to take screenshot in flutter web application by same method or any other method? I try it but didn't work.
|
35

let's say you want to take a screenshot of the FlutterLogo widget . wrap it in a RepaintBoundary with will creates a separate display list for its child . and provide with a key

var scr= new GlobalKey();
RepaintBoundary(
         key: scr,
         child: new FlutterLogo(size: 50.0,))

and then you can get the pngBytes by converting the boundary to an image

takescrshot() async {
  RenderRepaintBoundary boundary = scr.currentContext.findRenderObject();
  var image = await boundary.toImage();
  var byteData = await image.toByteData(format: ImageByteFormat.png);
  var pngBytes = byteData.buffer.asUint8List();
  print(pngBytes);
  }

4 Comments

I have a question => my widget Listview has more than 10 items, so the screen can't show all items and the capture image is only showing what we have in the screen. Is any method to capture the whole ListView even if the items is not showing on the screen?
@GPH I don't think it's possible, simply because those items are not even built, so no one knows how they would look like.
@MarcinSzałek , are you absolutely sure about that? It's important enough that I'm posting a question about it: stackoverflow.com/questions/57583965/…
how can we create jpg image? png image is transparent and mixed with background. Please share any suggestion.
10

here's the solution for flutter 2.0+ method for screenshot and share it on social media

 import 'package:flutter/rendering.dart';
        import 'package:flutter/services.dart';
        import 'dart:ui' as ui;
        import 'package:path_provider/path_provider.dart';
        import 'package:share/share.dart';
        
        GlobalKey previewContainer = new GlobalKey();
    
     @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            // Here we take the value from the MyHomePage object that was created by
            // the App.build method, and use it to set our appbar title.
            title: Text(widget.title),
          ),
          body: RepaintBoundary(
            key: previewContainer,
            child: Center(
              // Center is a layout widget. It takes a single child and positions it
              // in the middle of the parent.
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  Text(
                    'Take Screen Shot',
                  ),
                ],
              ),
            ),
          ),
          floatingActionButton: FloatingActionButton(
            onPressed: _captureSocialPng,
            tooltip: 'Increment',
            child: Icon(Icons.camera),
          ), // This trailing comma makes auto-formatting nicer for build methods.
        );
      }
    
        
          Future<void> _captureSocialPng() {
            List<String> imagePaths = [];
            final RenderBox box = context.findRenderObject() as RenderBox;
            return new Future.delayed(const Duration(milliseconds: 20), () async {
              RenderRepaintBoundary? boundary = previewContainer.currentContext!
                  .findRenderObject() as RenderRepaintBoundary?;
              ui.Image image = await boundary!.toImage();
              final directory = (await getApplicationDocumentsDirectory()).path;
              ByteData? byteData =
                  await image.toByteData(format: ui.ImageByteFormat.png);
              Uint8List pngBytes = byteData!.buffer.asUint8List();
              File imgFile = new File('$directory/screenshot.png');
              imagePaths.add(imgFile.path);
              imgFile.writeAsBytes(pngBytes).then((value) async {
                await Share.shareFiles(imagePaths,
                    subject: 'Share',
                    text: 'Check this Out!',
                    sharePositionOrigin: box.localToGlobal(Offset.zero) & box.size);
              }).catchError((onError) {
                print(onError);
              });
            });
          }

2 Comments

I tried this code. It works but produces a low-quality screenshot. It's kindof blurry. Any idea how to make it sharp?
Hey! i got an error when we cast as RenderRepaintBoundary?, says that 'type 'RenderFlex' is not a subtype of type 'RenderRepaintBoundary?' in type cast' when creating the boundary
1

Run

flutter screenshot

It will take the screenshot from your connected device and save that to your folder in which you are doing development it will save flutter_01.jpg like that in your folder

3 Comments

This takes the screenshot of my entire screen and not the emulator.
This doesn't capture a widget. It only takes a screenshot of the device's screen.
It gives me error: Screenshot not supported for Linux.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.