Capture a React Native view to an image. Support capture full content of webview.
iOS: For React Native version between
0.30.xand0.39.x, you should usereact-native-view-shot@1.5.1.
import { takeSnapshot } from "react-native-view-shot";
takeSnapshot(viewRef, {
format: "jpeg",
quality: 0.8
})
.then(
uri => console.log("Image saved to", uri),
error => console.error("Oops, snapshot failed", error)
);Checkout react-native-view-shot-example
Returns a Promise of the image URI.
viewis a reference to a React Native component.optionsmay include:width/height(number): the width and height of the image to capture.areaX/areaY/areaWidth/areaHeight(number): the specified area that you want to snapshot in a view.areaX/areaYindicates the upper-left corner. (The maximum areaHeight would be screen height)format(string): eitherpngorjpg/jpegorwebm(Android). Defaults topng.quality(number): the quality. 0.0 - 1.0 (default). (only available on lossy formats like jpeg)fullWebView(boolean): capture the whole view when capturing webview.scrollContent(boolean): automatically scroll webview and capture.( only available whenfullWebViewistrue). (iOS only)result(string), the method you want to use to save the snapshot, one of:"file"(default): save to a temporary file (that will only exist for as long as the app is running)."base64": encode as base64 and returns the raw string. Use only with small images as this may result of lags (the string is sent over the bridge). N.B. This is not a data uri, usedata-uriinstead."data-uri": same asbase64but also includes the Data URI scheme header.
path(string): The absolute path where the file get generated. Seedirsconstants for more information.folder(string): The folder where the file get generated in. Seedirsconstants for more information.slicePage(number): The max screen page that an image contains. The result will be an array of images. (only available whenscrollContentistrue) (iOS only).overflowTouchScrollEnabled(boolean): Indicates webview's attribute:-webkit-overflow-scrolling:touch.(only available whenfullWebViewistrue, iOS only).snapshotContentContainer(bool): if true and when view is a ScrollView, the "content container" height will be evaluated instead of the container height. (Android only)
By default, takeSnapshot will export in a temporary folder and the snapshot file will be deleted as soon as the app leaves. If you use the path option, you make the snapshot file more permanent and at a specific file location. To make file location more 'universal', the library exports some classic directory constants:
If you use the
pathoption, you own the file and manage its lifecycle: it won't get cleaned so be careful not leaking files on user's phone.
import { takeSnapshot, dirs } from "react-native-view-shot";
// cross platform dirs:
const { CacheDir, DocumentDir, MainBundleDir, MovieDir, MusicDir, PictureDir } = dirs;
// only available Android:
const { DCIMDir, DownloadDir, RingtoneDir, SDCardDir } = dirs;
takeSnapshot(viewRef, { path: PictureDir+"/foo.png" })
.then(
uri => console.log("Image saved to", uri),
error => console.error("Oops, snapshot failed", error)
);Model tested: iPhone 6 (iOS), Nexus 5 (Android).
| System | iOS | Android | Windows |
|---|---|---|---|
| View,Text,Image,.. | YES | YES | YES |
| WebView | YES | YES1 | YES |
| gl-react v2 | YES | NO2 | NO3 |
| react-native-video | NO | NO | NO |
| react-native-maps | YES | NO4 | NO3 |
- Only supported by wrapping a
<View collapsable={false}>parent and snapshotting it. - It returns an empty image (not a failure Promise).
- Component itself lacks platform support.
- But you can just use the react-native-maps snapshot function: https://github.com/airbnb/react-native-maps#take-snapshot-of-map
If you want to snapshot a WebView, you need to embed the webview in a View and takeSnapshot of the view.
Snapshots are not guaranteed to be pixel perfect. It also depends on the platform. Here is some difference we have noticed and how to workaround.
- Support of special components like Video / GL views is not guaranteed to work. In case of failure, the
takeSnapshotpromise gets rejected (the library won't crash). - It's preferable to use a background color on the view you rasterize to avoid transparent pixels and potential weirdness that some border appear around texts.
- you need to make sure
collapsableis set tofalseif you want to snapshot a View. Some content might even need to be wrapped into such<View collapsable={false}>to actually make them snapshotable! Otherwise that view won't reflect any UI View. (found by @gaguirre - if you implement a third party library and want to get back a File, you must first resolve the
Uri. thefileresult returns anUriso it's consistent with iOS and you can give it toImage.getSizefor instance. - if you run on Android L or above, and want to snapshot full content of WebView, you need to call
WebView.enableSlowWholeDocumentDraw()in youronCreate()ofMainApplication.javafile. Otherwise it only snapshot the visible area.
npm install --save react-native-view-shot
react-native link react-native-view-shot
- In XCode, in the project navigator, right click
Libraries➜Add Files to [your project's name] - Go to
node_modules➜react-native-view-shotand addRNViewShot.xcodeproj - In XCode, in the project navigator, select your project. Add
libRNViewShot.ato your project'sBuild Phases➜Link Binary With Libraries - Run your project (
Cmd+R)<
- Open up
android/app/src/main/java/[...]/MainActivity.java
- Add
import fr.greweb.reactnativeviewshot.RNViewShotPackage;to the imports at the top of the file - Add
new RNViewShotPackage()to the list returned by thegetPackages()method
- Append the following lines to
android/settings.gradle:include ':react-native-view-shot' project(':react-native-view-shot').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-view-shot/android') - Insert the following lines inside the dependencies block in
android/app/build.gradle:compile project(':react-native-view-shot')
- In Visual Studio, in the solution explorer, right click on your solution then select
Add➜ExisitingProject - Go to
node_modules➜react-native-view-shotand addRNViewShot.csproj(UWP) or optionallyRNViewShot.Net46.csproj(WPF) - In Visual Studio, in the solution explorer, right click on your Application project then select
Add➜Reference - Under the projects tab select
RNViewShot(UWP) orRNViewShot.Net46(WPF)
- To initial iOS work done by @jsierles in https://github.com/jsierles/react-native-view-snapshot
- To React Native implementation of takeSnapshot in iOS by @nicklockwood
- To Windows implementation by @ryanlntn
