README.md 4.4 KB
Newer Older
1
 <img src="https://github.com/SachinGanesh/screenshot/raw/master/assets/sc.png" alt="screenshot"/>
Sachin Ganesh's avatar
Sachin Ganesh committed
2

Sachin Ganesh's avatar
Sachin Ganesh committed
3
A simple package to capture widgets as Images. Now you can also capture the widgets that are not rendered on the screen!
Sachin Ganesh's avatar
Sachin Ganesh committed
4

5
This package wraps your widgets inside [RenderRepaintBoundary](https://docs.flutter.io/flutter/rendering/RenderRepaintBoundary-class.html)
Sachin Ganesh's avatar
Sachin Ganesh committed
6 7

[Source](https://stackoverflow.com/a/51118088)
Sachin Ganesh's avatar
Sachin Ganesh committed
8

Sachin Ganesh's avatar
Sachin Ganesh committed
9 10 11
| | | 
| :---: | :---: |
|<img src="https://github.com/SachinGanesh/screenshot/raw/master/assets/screenshot.gif" alt="screenshot"/>|<p>&nbsp; Capture a `widget`:</p><img src="https://github.com/SachinGanesh/screenshot/raw/master/assets/code1.png" alt="screenshot"/><hr><p>&nbsp;Capture an `invisible widget` (a widget which is not part of the widget tree):</p><img src="https://github.com/SachinGanesh/screenshot/raw/master/assets/code2.png" alt="screenshot"/>|
12 13

---
Sachin Ganesh's avatar
Sachin Ganesh committed
14 15
## Getting Started

Sachin Ganesh's avatar
Sachin Ganesh committed
16
This handy package can be used to capture any Widget including full screen screenshots & individual widgets like `Text()`.
Sachin Ganesh's avatar
Sachin Ganesh committed
17

Sachin Ganesh's avatar
Sachin Ganesh committed
18
1) Create Instance of `Screenshot Controller`
Sachin Ganesh's avatar
Sachin Ganesh committed
19 20 21 22

```dart
class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;
ritheshSalyan's avatar
ritheshSalyan committed
23
  Uint8List _imageFile;
Sachin Ganesh's avatar
Sachin Ganesh committed
24 25 26 27 28 29 30 31 32 33 34 35

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

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
  }
  ...
}
```
Sachin Ganesh's avatar
Sachin Ganesh committed
36
2) Wrap the widget that you want to capture inside `Screenshot` Widget. Assign the controller to `screenshotController` that you have created earlier
Sachin Ganesh's avatar
Sachin Ganesh committed
37 38 39 40 41 42 43 44

```dart
Screenshot(
    controller: screenshotController,
    child: Text("This text will be captured as image"),
),
```

Sachin Ganesh's avatar
Sachin Ganesh committed
45
3) Take the screenshot by calling `capture` method. This will return a `Uint8List`
Sachin Ganesh's avatar
Sachin Ganesh committed
46 47

```dart
ritheshSalyan's avatar
ritheshSalyan committed
48
screenshotController.capture().then((Uint8List image) {
Sachin Ganesh's avatar
Sachin Ganesh committed
49 50 51 52 53 54 55 56
    //Capture Done
    setState(() {
        _imageFile = image;
    });
}).catchError((onError) {
    print(onError);
});
```
57 58
---
## Capturing Widgets that are not in the widget tree
Sachin Ganesh's avatar
Sachin Ganesh committed
59

Sachin Ganesh's avatar
Sachin Ganesh committed
60
You can capture invisible widgets by calling `captureFromWidget` and passing a widget tree to the function
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75

```dart
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
  });
},
Sachin Ganesh's avatar
Sachin Ganesh committed
76 77 78
```


79
---
ritheshSalyan's avatar
ritheshSalyan committed
80
## Saving images to Specific Location
Sachin Ganesh's avatar
Sachin Ganesh committed
81
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](https://pub.dartlang.org/packages/path_provider)
ritheshSalyan's avatar
ritheshSalyan committed
82 83 84

### Note

Sachin Ganesh's avatar
Sachin Ganesh committed
85
>Method `captureAndSave` is not supported for `web`. 
ritheshSalyan's avatar
ritheshSalyan committed
86

Sachin Ganesh's avatar
Sachin Ganesh committed
87 88 89

```dart
final directory = (await getApplicationDocumentsDirectory ()).path; //from path_provide package
ritheshSalyan's avatar
ritheshSalyan committed
90 91
String fileName = DateTime.now().microsecondsSinceEpoch;
path = '$directory';
Sachin Ganesh's avatar
Sachin Ganesh committed
92

ritheshSalyan's avatar
ritheshSalyan committed
93 94 95
screenshotController.captureAndSave(
    path //set path where screenshot will be saved
    fileName:fileName 
Sachin Ganesh's avatar
Sachin Ganesh committed
96 97
);
```
98
---
Sachin Ganesh's avatar
Sachin Ganesh committed
99 100 101 102
## 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.

103
### Note:
Sachin Ganesh's avatar
Sachin Ganesh committed
104 105 106 107 108 109
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.


```dart
110 111
double pixelRatio = MediaQuery.of(context).devicePixelRatio;

Sachin Ganesh's avatar
Sachin Ganesh committed
112
screenshotController.capture(
Sachin Ganesh's avatar
Sachin Ganesh committed
113
    pixelRatio: pixelRatio //1.5
Sachin Ganesh's avatar
Sachin Ganesh committed
114 115
)
```
Sachin's avatar
Sachin committed
116
---
Sachin's avatar
Sachin committed
117
Sometimes rastergraphics like images may not be captured by the plugin with default configurations. The issue is discussed [here](https://api.flutter.dev/flutter/flutter_driver/FlutterDriver/screenshot.html). 
Sachin's avatar
Sachin committed
118 119 120 121 122 123 124 125 126 127 128

```
...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. 

```dart
screenshotController.capture(delay: Duration(milliseconds: 10))
```
Sachin Ganesh's avatar
Sachin Ganesh committed
129
---
130
## Known Issues
Sachin Ganesh's avatar
Sachin Ganesh committed
131
- **`Platform Views are not supported. (Example: Google Maps, Camera etc)`**
Sachin Ganesh's avatar
Sachin Ganesh committed
132
---