# react-native-view-shot ![](https://img.shields.io/npm/v/react-native-view-shot.svg) ![](https://img.shields.io/badge/react--native-%2040+-05F561.svg) Snapshot a React Native view and save it to an image. > For React Native version between `0.30.x` and `0.39.x`, you should use `react-native-view-shot@1.5.1`. ## Usage ```js 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) ); ``` ### Example [Checkout react-native-view-shot-example](https://github.com/gre/react-native-view-shot-example) ## Full API ### `takeSnapshot(view, options)` 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)*: either `png` or `jpg`/`jpeg` or `webm` (Android). Defaults to `png`. - **`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, use `data-uri` instead*. - `"data-uri"`: same as `base64` but also includes the [Data URI scheme](https://en.wikipedia.org/wiki/Data_URI_scheme) header. - **`path`** *(string)*: The absolute path where the file get generated. See *`dirs` 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. ### `dirs` constants 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: ```js 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) ); ``` ## Supported views Model tested: iPhone 6 (iOS), Nexus 5 (Android). | System | iOS | Android | |--------------------|--------------------|-------------------| | View,Text,Image,.. | YES | YES | | WebView | YES | YES1 | | gl-react v2 | YES | NO2 | | react-native-video | NO | NO | | react-native-maps | YES | [NO](https://github.com/gre/react-native-view-shot/issues/36) | > 1. Only supported by wrapping a `` parent and snapshotting it. 2. It returns an empty image (not a failure Promise). ## Caveats 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. ### specific to Android implementation - you need to make sure `collapsable` is set to `false` if you want to snapshot a **View**. Some content might even need to be wrapped into such `` to actually make them snapshotable! Otherwise that view won't reflect any UI View. ([found by @gaguirre](https://github.com/gre/react-native-view-shot/issues/7#issuecomment-245302844)) - if you implement a third party library and want to get back a File, you must first resolve the `Uri`. (the `file` result returns an `Uri` so it's consistent with iOS and can be given to APIs like `Image.getSize`) ## Getting started ``` npm install --save react-native-view-shot ``` ### Mostly automatic installation ``` react-native link react-native-view-shot ``` ### Manual installation #### iOS 1. In XCode, in the project navigator, right click `Libraries` ➜ `Add Files to [your project's name]` 2. Go to `node_modules` ➜ `react-native-view-shot` and add `RNViewShot.xcodeproj` 3. In XCode, in the project navigator, select your project. Add `libRNViewShot.a` to your project's `Build Phases` ➜ `Link Binary With Libraries` 4. Run your project (`Cmd+R`)< #### Android 1. 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 the `getPackages()` method 2. 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') ``` 3. Insert the following lines inside the dependencies block in `android/app/build.gradle`: ``` compile project(':react-native-view-shot') ``` #### Windows Stay tuned, https://github.com/gre/react-native-view-shot/pull/45 will be merged soon! ## Thanks - 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