Capture a React Native view to an image.
iOS: For React Native version between
0.30.x
and0.39.x
, you should use[email protected]
.
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.
view
is a reference to a React Native component.options
may include:width
/height
(number): the width and height of the final image (resized from the View bound. don't provide it if you want the original pixel size).format
(string): eitherpng
orjpg
/jpeg
orwebm
(Android). Defaults topng
.quality
(number): the quality. 0.0 - 1.0 (default). (only available on lossy formats like jpeg)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-uri
instead."data-uri"
: same asbase64
but also includes the Data URI scheme header.
path
(string): The absolute path where the file get generated. Seedirs
constants for more information.snapshotContentContainer
(bool): if true and when view is a ScrollView, the "content container" height will be evaluated instead of the container height.
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:
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 | NO | 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.
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
takeSnapshot
promise 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
collapsable
is set tofalse
if 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
. (thefile
result returns anUri
so it's consistent with iOS and can be given to APIs likeImage.getSize
)
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-shot
and addRNViewShot.xcodeproj
- In XCode, in the project navigator, select your project. Add
libRNViewShot.a
to 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-shot
and 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