Flutter Screenshot Library

Overview

screenshot

A simple package to capture widgets as Images. Now you can also capture the widgets that are not rendered on the screen!

This package wraps your widgets inside RenderRepaintBoundary

Source

screenshot

  Capture a widget:

screenshot

 Capture an invisible widget (a widget which is not part of the widget tree):

screenshot

Getting Started

This handy package can be used to capture any Widget including full screen screenshots & individual widgets like Text().

  1. Create Instance of Screenshot Controller
class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;
  Uint8List _imageFile;

  //Create an instance of ScreenshotController
  ScreenshotController screenshotController = ScreenshotController(); 

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
  }
  ...
}
  1. Wrap the widget that you want to capture inside Screenshot Widget. Assign the controller to screenshotController that you have created earlier
Screenshot(
    controller: screenshotController,
    child: Text("This text will be captured as image"),
),
  1. Take the screenshot by calling capture method. This will return a Uint8List
screenshotController.capture().then((Uint8List image) {
    //Capture Done
    setState(() {
        _imageFile = image;
    });
}).catchError((onError) {
    print(onError);
});

Capturing Widgets that are not in the widget tree

You can capture invisible widgets by calling captureFromWidget and passing a widget tree to the function

screenshotController
      .captureFromWidget(Container(
          padding: const EdgeInsets.all(30.0),
          decoration: BoxDecoration(
            border:
                Border.all(color: Colors.blueAccent, width: 5.0),
            color: Colors.redAccent,
          ),
          child: Text("This is an invisible widget")))
      .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 package
String 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: const Duration(milliseconds: 10)).then((Uint8List image) async {
      if (image != null) {
        final directory = await getApplicationDocumentsDirectory();
        final imagePath = await File('${directory.path}/image.png').create();
        await imagePath.writeAsBytes(image);

        /// Share Plugin
        await Share.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.

double pixelRatio = MediaQuery.of(context).devicePixelRatio;

screenshotController.capture(
    pixelRatio: pixelRatio //1.5
)

Sometimes rastergraphics like images may not be captured by the plugin with default configurations. The issue is discussed here.

...screenshot is taken before the GPU thread is done rasterizing the frame 
so the screenshot of the previous frame is taken, which is wrong.

The solution is to add a small delay before capturing.

screenshotController.capture(delay: Duration(milliseconds: 10))

Known Issues

  • Platform Views are not supported. (Example: Google Maps, Camera etc)issue

Comments
  • Issue with google maps

    Issue with google maps

    Hello, I tried using this plugin with a widget with google maps in it. It captures the screen but without the maps part. It appears blank. Appreciate if you can help.

    Thanks

    opened by A-EL 14
  • Saving a list of widgets throws findRenderObject was called on null exception.

    Saving a list of widgets throws findRenderObject was called on null exception.

    I have a list of items in ListView(), not ListView.builder(). And in the ListView each child is wrapped with Screenshot widget. When the ListView is built I store the Screenshot controller for each widget in a list. When trying to capture only the first widget gets captured and then I get this exception

    /flutter ( 2557): Caught error: NoSuchMethodError: The method 'findRenderObject' was called on null.
    I/flutter ( 2557): Receiver: null
    I/flutter ( 2557): Tried calling: findRenderObject()
    I/flutter ( 2557): #0      ScreenshotController.capture.<anonymous closure>
    package:screenshot/screenshot.dart:41
    I/flutter ( 2557): #1      new Future.delayed.<anonymous closure> (dart:async/future.dart:326:39)
    I/flutter ( 2557): #2      _rootRun (dart:async/zone.dart:1182:47)
    I/flutter ( 2557): #3      _CustomZone.run (dart:async/zone.dart:1093:19)
    I/flutter ( 2557): #4      _CustomZone.runGuarded (dart:async/zone.dart:997:7)
    I/flutter ( 2557): #5      _CustomZone.bindCallbackGuarded.<anonymous closure> (dart:async/zone.dart:1037:23)
    I/flutter ( 2557): #6      _rootRun (dart:async/zone.dart:1190:13)
    I/flutter ( 2557): #7      _CustomZone.run (dart:async/zone.dart:1093:19)
    I/flutter ( 2557): #8      _CustomZone.bindCallback.<anonymous closure> (dart:async/zone.dart:1021:23)
    I/flutter ( 2557): #9      Timer._createTimer.<anonymous closure> (dart:async-patch/timer_patch.dart:18:15)
    I/flutter ( 2557): #10     _Timer._runTimers (dart:isolate-patch/timer_impl.dart:397:19)
    I/flutter ( 2557): #11     _Timer._handleMessage (dart:isolate-patch/timer_impl.dart:428:5)
    I/flutter ( 2557): #12     _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:168:12)
    
    
    opened by tehsunnliu 7
  • ScreenShot from video_player

    ScreenShot from video_player

    Hi,

    I am using this lib and the https://pub.dev/packages/video_player, but seems dont work correctly.

    The generate image is always black, anyone knows how to fix this?

    Thanks

    opened by salime45 7
  • Getting

    Getting "NoSuchMethodError: The method 'toImage' was called on null." Exception

    screenshot: ^0.2.0 was working perfectly fine till I updated Flutter to 2.0 and Screenshot Package to screenshot: ^1.0.0-nullsafety.1 I started getting "NoSuchMethodError: The method 'toImage' was called on null." exception. I'm calling screenshotController.capture() method. The exception is thrown inside captureAsUiImage() method when it tries to call boundary.toImage(...);

    This happens when I try to capture multiple widgets screenshot. I've multiple CardView inside a Column which is wrapped with Screenshot widget. When I try to all .capture() for each ScreenshotController only the first call to capture works and for the rest it throws NoSuchMethodError I've also tried increasing the delay, however, no success.

    opened by tehsunnliu 6
  • Is it work in Webview?

    Is it work in Webview?

    I have been trying to screen capture a picture of WebView and the result that I get is an empty picture. Do you have a solution to solve them? I had no error in the command line, it only sent me an empty picture. Thank you in advance.

    opened by izzabellerina 6
  • Screenshot elements not rendered on screen?

    Screenshot elements not rendered on screen?

    Hello @SachinGanesh thanks for the package. I'm trying to screenshot a part of the widget tree but I need to add some custom widgets to the screenshot, those widgets in the screenshot should not be shown on the screen. Is there a way to achieve this using this package?

    opened by vedantrathore 6
  • Black Bars on screenshot image

    Black Bars on screenshot image

    Hi, I'm creating custom certificates with users name on it and using this library to take a screenshot of the stack. The screenshot generated has black bars on the top and bottom of the image. Is there any way to remove them? I don't want to simply change the colour but entirely remove them. I've placed the stack inside the Screenshot widget and am using the screenshot controller to capture the image. image

    opened by Pranet-Hiranandani 5
  • Convert Uint8List to File

    Convert Uint8List to File

    I am using the previous version 0.2.0 of screenshot and it support capture as File. With the new 0.3.0, it is now Uint8List. How do I convert Uint8List into File ?

    opened by tonyteo72 5
  • Is this working on web?

    Is this working on web?

    I am trying to use this with flutter web but I think it might be not supported because I get an error:

    Assertion failed: org-dartlang-sdk:///flutter_web_sdk/lib/_engine/engine/surface/scene_builder.dart:111:16
    matrix4[0] == window.devicePixelRatio &&
               matrix4[5] == window.devicePixelRatio
    is not true
    
    opened by quetool 5
  • Can not take screenshot of Whole list view

    Can not take screenshot of Whole list view

    Hello,

    I have 10 items in a list and if they can not visible in screen they are not showing in screenshot also. how can i capture screenshot for whole list of data.

    opened by WorthPly 5
  • No MediaQuery ancestor could be found

    No MediaQuery ancestor could be found

    Hi,Dear

    I got this Exception

    ======== Exception caught by widgets library =======================================================
    The following assertion was thrown building CircleAvatar(dirty):
    No MediaQuery widget ancestor found.
    

    when I want share img came from captureFromWidget

                  screenshotController
                      .captureFromWidget(sharedCard,
                          delay: Duration(milliseconds: 10),
                      pixelRatio:1.5)
                      .then((capturedImage) async {
                    ShowCapturedWidget(context, capturedImage!);
                  }).catchError((onError) {
                    print(onError);
                  });
                },
    

    which means ,the widge named CircleAvatar( contained by shardCard here), have no MediaQuery ancestor, sure it is!

    what I want to do ,is capturing widget (card) with some message, to share with people and add the message( who I am ,from which app), seems reasonable, ha

    so , sharedCard is a container contains card which visible and some text which not visible, so I used captureFromWidget

    as we see the Exception, there needs a MediaQuery ancestor ,how can I handle this? to warp shareCard with MetariaApp?

    opened by yichaosun 4
  • The getter 'width' was called on null 'captureFromWidget'

    The getter 'width' was called on null 'captureFromWidget'

    I am trying to capture an image of a progress indicator using the captureFromWidget method. However, I keep getting the error

    NoSuchMethodError: The getter 'width' was called on null. Receiver: null Tried calling: width

    I am not sure where this error is coming from, and I believe I have setup the capture correctly. My function is below.

    Future<String> progressBarPath(double progress) async {
        final progressFile = File('${(await getTemporaryDirectory()).path}/image.png');
        var indicator = LinearPercentIndicator(
          percent: progress > 1.0 ? 1.0 : progress,
          width: 100,
          lineHeight: 13,
          animation: true,
          animationDuration: 1000,
          progressColor: FlutterFlowTheme.primaryColor,
          backgroundColor: Color(0xFFF1F4F8),
          center: Text(
            formatNumber(
                progress > 1.0 ? 1.0 : progress,
                formatType: FormatType.percent),
            style: FlutterFlowTheme.bodyText1.override(
              fontFamily: 'Lato',
              color: Colors.black,
              fontSize: 12,
              fontWeight: FontWeight.bold,
            ),
          ),
          barRadius: Radius.circular(20),
        );
        screenshotController.captureFromWidget(
          InheritedTheme.captureAll(context, Material(child: indicator)),
              delay: Duration(seconds: 1),
        ).then((capturedProgress) async {
          await progressFile.create(recursive: true);
          await progressFile.writeAsBytes(capturedProgress);
        });
        print(progressFile.path);
        return progressFile.path;
      }
    
    opened by DennisAshford 1
  • Screenshot doesn't capture image when google ads are used

    Screenshot doesn't capture image when google ads are used

    Screenshot package independently works well. But if Google ads are integrated in app then screenshot is not able to capture image.

    Here is a reproducible sample repo: ads_screenshot

    Here is the specific code from the above linked repo causing issues:

    _bannerAd!.load();
    

    load method on google ads is the line causing issues. As long is it is called, screenshot will not capture image but if it is commented out then screenshot will work as expected. Tried on Android, never tried on iOS.

    opened by chinmaysarupria 0
  • screenshot not full get screen when NestedScrollView

    screenshot not full get screen when NestedScrollView

    if use SingleChildScrollView, screenshot work success.

    But I use sliver widget in my page when root node NestedScrollView So... full screen crop to display size. How fix ?

    
    ScrollController _scrollControlle  = ScrollController();
    ScreenshotController screenshotController = ScreenshotController();
    
     @override
      Widget build(BuildContext context) {
    
        return 
         Scaffold(
            body: Screenshot(
              controller: screenshotController,
              child: NestedScrollView(
                controller: _scrollController,
                headerSliverBuilder: (BuildContext context, bool boxIsScrolled) {
                  return <Widget>[
                    // User information section
                    SliverToBoxAdapter(child: userInfo()),
    
                    // Tap bar
                    SliverPersistentHeader(
                      delegate: CustomSliverDelegate(_tabController),
                      pinned: true,
                      floating: true,
                    ),
                  ];
                },
                body: TabBarView(
                  controller: _tabController,
                  children: <Widget>[
                    ...
                  ],
                ),
            )),
        );
    
    
    opened by gradus0 0
  • Capture of a widget which contains an image doesn't capture the image part of the widget

    Capture of a widget which contains an image doesn't capture the image part of the widget

    Expected: capture of myWidget() will include myWidget's logo Actual: everything is captured except the logo Additional info: see main.dart Full disclosure: I'm not a developer, I'm just trying to prototype a business idea

    Possible dup of #63 and #82 but none of those suggestions helped, so may be a new issue.

    What have I tried? I have tried using screenshotController.captureFromWidget I have tried adjusting the delay (many values from 10ms up to 3000ms) I have tried Image.asset('images/logo.png') [this is actually where I started but the NetworkImage has the same issue and is easier to share with you]

    I have tried two ways of forcing the canvas kit to be the renderer: first way:

    flutter run -d chrome --web-renderer canvaskit second way (in web/index.js added just above ""):

    but nothing I've tried works. I'm using the latest stable of both dart and flutter. Any help appreciated. Paul P.S. apologies, I couldn't figure out how to paste main.dart and keep the formatting, so have just attached it as a txt file

    main.dart.txt

    opened by gh-pap 3
  • captureFromWidget on ListView causes Bottom Overflowed - cuts off screenshot

    captureFromWidget on ListView causes Bottom Overflowed - cuts off screenshot

    What is the correct way to use captureFromWidget with a height that is larger than the screen? I have tried to manipulate the widgets in several ways, but I am unable to get it to capture a height that is larger than the screen.

    opened by m-j-g 5
Releases(v1.2.3)
Owner
Sachin
AR | VR | Flutter | Gamification
Sachin
QR.Flutter is a Flutter library for simple and fast QR code rendering via a Widget or custom painter.

QR.Flutter is a Flutter library for simple and fast QR code rendering via a Widget or custom painter. Need help? Please do not submit an issue for a "

Yakka 612 Jan 4, 2023
Flutter library to create beautiful surveys (aligned with ResearchKit on iOS)

SurveyKit: Create beautiful surveys with Flutter (inspired by iOS ResearchKit Surveys)

QuickBird Studios 90 Dec 28, 2022
Complete Flutter OpenIdConnect Library

OpenIdConnect for Flutter Standards compliant OpenIdConnect library for flutter that supports: Code flow with PKCE (the evolution of implicit flow). T

null 50 Dec 24, 2022
🎞 Flutter media playback, broadcast & recording library for Windows, Linux & macOS. Written in C++ using libVLC & libVLC++. (Both audio & video)

dart_vlc Flutter media playback, broadcast, recording & chromecast library for Windows, Linux & macOS. Written in C++ using libVLC & libVLC++. Install

Hitesh Kumar Saini 417 Dec 29, 2022
Flutter example project to run Solidity smart contracts using web3Dart library

Fluthereum Description Flutter example project to run Solidity smart contracts using web3Dart library Dependencies web3dart: A dart library that conne

Marcos Carlomagno 72 Dec 27, 2022
Demo library index written in Flutter

demo_books A new Flutter project. Getting Started This project is a starting point for a Flutter application. A few resources to get you started if th

Nemanja Stošić 1 Sep 20, 2022
A playground for me to learn the Riverpod state management library in Flutter.

clothes_shop A new Flutter project. Getting Started This project is a starting point for a Flutter application. A few resources to get you started if

Benhenneda Majid 2 Oct 25, 2021
Playify is a Flutter plugin for play/pause/seek songs, fetching music metadata, and browsing music library.

Playify Playify is a Flutter plugin for play/pause/seek songs, fetching music metadata, and browsing music library. Playify was built using iOS's Medi

Ibrahim Berat Kaya 32 Dec 14, 2022
A typesafe sqlite persistence library for flutter

Warning: This library has been deprecated. Please use moor instead. It requires less work to set up, needs less boilerplate code and has more features

Simon Binder 59 Jan 18, 2021
A library of Flutter to add a new style in the navigation bar.

Navigation Dot Bar Una libreria de Flutter, el cual agrega un BottomNavigationBar con un mejor estilo. Inspirada en la aplicacion "Reflectly" Como usa

null 38 Oct 17, 2022
A flutter todo/task listing example app with advance state management using `Momentum` library.

A flutter todo/task listing example app with advanced state management using Momentum library. Simple on the outside but powerful in the inside. This

xamantra 17 Oct 11, 2022
A declarative library with an easy-to-use interface for building Flutter applications on AWS.

Amplify Flutter AWS Amplify provides a declarative and easy-to-use interface across different categories of cloud operations. Our default implementati

AWS Amplify 1.1k Jan 5, 2023
A fast and space efficient library to deal with data in Dart, Flutter and the web.

Dart Data Dart Data is a fast and space efficient library to deal with data in Dart, Flutter and the web. As of today this mostly includes data struct

Lukas Renggli 14 Nov 4, 2022
A powerful Flutter chat UI component library and business logic for Tencent Cloud Chat, creating seamless in-app chat modules for delightful user experiences.

<style> .button-9 { appearance: button; backface-visibility: hidden; background-color: #1d52d9; border-radius: 6px; border-width: 0; box-shadow: rgba(

Tencent Cloud 63 Aug 11, 2023
A type-safe command-line parsing library for Dart

plade Plade is a type-safe CLI parsing library for Dart. Highlights Fully type-safe and null-safe. Support for a variety of different parsing styles (

Ryan Gonzalez 6 Jan 1, 2022
Agent library for Internet Computer, in Dart

agent_dart An agent library built for Internet Computer, a plugin package for dart and flutter apps. Developers can build ones to interact with Dfinit

null 87 Dec 31, 2022
ThingsBoard PE API client library for Dart developers.

ThingsBoard PE API client library for Dart developers. It's compatible with TB PE 3.3.0. Usage A simple usage example: import 'package:thingsboard_pe_

ThingsBoard - Open-source IoT Platform 45 Sep 28, 2022
A Dart library for creating a Dart object to represent directory trees.

Directory Tree A Dart library for creating a Dart object to represent directory trees. Getting Started Import and initialize package import 'package:d

Chiziaruhoma Ogbonda 5 Dec 1, 2021
more code then the original with cupertino library

this version only update flutter cupertino library for crud purpose with backend api this is not stable version yet both side. Youtube for flutter cup

nobody but me 1 Aug 21, 2022