gre / react-native-view-shot Goto Github PK
View Code? Open in Web Editor NEWSnapshot a React Native view and save it to an image
Home Page: https://github.com/gre/react-native-view-shot-example
License: MIT License
Snapshot a React Native view and save it to an image
Home Page: https://github.com/gre/react-native-view-shot-example
License: MIT License
to match the same behavior of the iOS implementation.
Hi, I would like to capture my WebView. In the simulator, it works fine, and I can store it to any Dir. However, when I run the code using debug mode or release mode on my device, it always shows the same error. Could you please point out what's wrong here? Thanks.
Here is the error message:
2017-03-07 11:33:35.413 [info][tid:com.facebook.react.JavaScript] { [Error: Failed to capture view snapshot]
line: 2813,
column: 24,
sourceURL: 'file:///var/containers/Bundle/Application/F030ED8C-8964-4991-91A6-6A5AFDFC23A5/Altizure.app/main.jsbundle',
framesToPop: 1,
code: 'EUNSPECIFIED',
nativeStackIOS:
[ '0 Altizure 0x00000001001e0634 RCTJSErrorFromCodeMessageAndNSError + 152',
'1 Altizure 0x000000010016a1b4 __41-[RCTModuleMethod processMethodSignature]_block_invoke_2.224 + 184',
'2 Altizure 0x00000001003a8b74 __54-[RNViewShot takeSnapshot:withOptions:resolve:reject:]_block_invoke + 988',
'3 Altizure 0x000000010021c78c __29-[RCTUIManager flushUIBlocks]_block_invoke + 660',
'4 libdispatch.dylib 0x00000001008d9258 _dispatch_call_block_and_release + 24',
'5 libdispatch.dylib 0x00000001008d9218 _dispatch_client_callout + 16',
'6 libdispatch.dylib 0x00000001008de280 _dispatch_main_queue_callback_4CF + 1200',
'7 CoreFoundation 0x000000018c2aa810 <redacted> + 12',
'8 CoreFoundation 0x000000018c2a83fc <redacted> + 1660',
'9 CoreFoundation 0x000000018c1d62b8 CFRunLoopRunSpecific + 444',
'10 GraphicsServices 0x000000018dc8a198 GSEventRunModal + 180',
'11 UIKit 0x000000019221d7fc <redacted> + 684',
'12 UIKit 0x0000000192218534 UIApplicationMain + 208',
'13 Altizure 0x00000001000fa144 main + 124',
'14 libdyld.dylib 0x000000018b1b95b8 <redacted> + 4' ],
domain: 'RCTErrorDomain',
userInfo: null }
Development environment:
Xcode 8.2.1
iOS 10.2
ReactNative 0.42
To reproduce:
async takeSnapshot() {
try {
this.snapshot = await takeSnapshot(this.modelContainer, {
format: "jpeg",
quality: 0.7,
path: PictureDir + "/snapshot.jpeg"
});
console.log(this.snapshot);
} catch (err) {
console.log(err);
}
}
<View style={styles.viewer} ref={(ref) => { this.modelContainer = ref; }}>
<WkWebView
ref={(ref) => { this.webview = ref; }}
startInLoadingState={true}
renderLoading={this.renderLoading}
source={require('./earth.html')}
onMessage={(event) => this.shareSheet.earth(event.body, this.snapshot)}
injectedJavaScript={jsCode}
javaScriptEnabled={true}
/>
</View>
viewer: {
flex: 1,
zIndex: -1,
backgroundColor: '#232323'
}
do anyone have a solution for this ?
if you want to snap a big view, it won't work.
W/View: ReactViewGroup not displayed because it is too large to fit into a software layer (or drawing cache), needs 41990400 bytes, only 8294400 available
I can't seem to Image.getSize
nor require()
the saved image on Android. Works fine on iOS.
takeSnapshot(this.refs.content, {
format: 'jpeg',
quality: 0.8,
})
.then((response) => {
Image.getSize(response, (width, height) => {
this.setState({
modalBackdropProps: {
imageSize: {
height,
width,
},
source: {
uri: response,
},
},
});
});
});
The image path is: /data/data/<packageName>/cache/ReactNative_snapshot_image_<timestamp>.jpeg
.
For Image.getSize
I get: "Error: Unsupported uri scheme!"
I was tried the example code and i got a uri like this:
file:///data/user/0/com.last/cache/ReactNative-snapshot-image1446502249.png
Is there any way to change the uri into the real path? just like:
"/storage/emulated/0/Pictures/ReactNative-snapshot-image799473449.png"
so i could use the path for the CameraRoll library from react native like:
CameraRoll.saveToCameraRoll(path,'photo')
Thanks and please help hehe
Hi I'm facing this issue on Samsung Galaxy 7 and Moto G3. Please let me know whats wrong with this.
Is there anyway to store the screenshot to Phone's camera roll/gallery instead of the tmp directory?
Hi, I have a long page which user have to scroll down to read all of it. This page is something user want to share on social media, so I need to take a shot whole scrollview content.
So, I've tried to use this package to take the image but it only returns what's visible on screen at the moment, I've also tried snapshotContentContainer option but no luck so far.
Hi,
is it possible to capture a whole View, even the parts that are not yet on screen (like in a scrollview)?
Or even better: capture a View that has not yet been given to the render method?
e.g.
createView(){
return <View>
<Text>Hello World</Text>
</View>
}
...
RNViewShot.takeSnapshot(this.createView(), {
format: 'png',
result: 'file',
});
Is this planned, and would this at all be possible with the current architecture?
Best, Tim
webview source require this html,captures blank, in the react-native-view-shot-example project @gre
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>ECharts</title>
<!-- 引入 echarts.js -->
<script src="http://cdn.bootcss.com/echarts/3.4.0/echarts.min.js"></script>
</head>
<body>
<!-- 为ECharts准备一个具备大小(宽高)的Dom -->
<div id="main" style="width: 600px;height:400px;"></div>
<script type="text/javascript">
// 基于准备好的dom,初始化echarts实例
var myChart = echarts.init(document.getElementById('main'));
// 指定图表的配置项和数据
var symbolSize = 20;
var data = [[15, 0], [-50, 10], [-56.5, 20], [-46.5, 30], [-22.1, 40]];
var points = [];
option = {
title: {
text: 'Click to Add Points'
},
tooltip: {
formatter: function (params) {
var data = params.data || [0, 0];
return data[0].toFixed(2) + ', ' + data[1].toFixed(2);
}
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis: {
min: -60,
max: 20,
type: 'value',
axisLine: { onZero: false }
},
yAxis: {
min: 0,
max: 40,
type: 'value',
axisLine: { onZero: false }
},
series: [
{
id: 'a',
type: 'line',
smooth: true,
symbolSize: symbolSize,
data: data
}
]
};
// 使用刚指定的配置项和数据显示图表。
myChart.setOption(option);
</script>
</body>
</html>
I did your example but it always throw the error
error save: ReferenceError: file is not defined
at http://localhost:8081/index.ios.bundle?platform=ios&dev=true&minify=false:78636:31
at tryCallOne (http://localhost:8081/index.ios.bundle?platform=ios&dev=true&minify=false:32137:8)
at http://localhost:8081/index.ios.bundle?platform=ios&dev=true&minify=false:32223:9
at http://localhost:8081/index.ios.bundle?platform=ios&dev=true&minify=false:5651:49
at Object.callTimer (http://localhost:8081/index.ios.bundle?platform=ios&dev=true&minify=false:4156:1)
at Object.callImmediatesPass (http://localhost:8081/index.ios.bundle?platform=ios&dev=true&minify=false:4260:19)
at Object.callImmediates (http://localhost:8081/index.ios.bundle?platform=ios&dev=true&minify=false:4275:25)
at http://localhost:8081/index.ios.bundle?platform=ios&dev=true&minify=false:3962:43
at guard (http://localhost:8081/index.ios.bundle?platform=ios&dev=true&minify=false:3794:1)
at MessageQueue.__callImmediates (http://localhost:8081/index.ios.bundle?platform=ios&dev=true&minify=false:3962:1)
My code
snapshot = refname => () => {
console.log(refname)
RNViewShot.takeSnapshot(this.refs[refname], {format: "jpeg", quality: 0.8, result: "file"})
.then(
uri => {
console.log("Image saved to ", file);
}
)
.catch(error => console.log('error save: ', error));
}
Hello first of all great package 😄 .
This is more a question than an issue, but trying to export a MapView from https://github.com/airbnb/react-native-maps the map itself is a blank. Do you have any idea on why this could be happening?. Could it be that is probably a native element so this exporter does not know how to render something that is not a react-native rendered element? (I imagine i can be completely wrong on my self-explanation on why it does not work)
I'm getting this issue if my view reference did not specify a backgroundColor.
so the code works fine if I take a Snapshot with the below viewRef
<View
style={{backgroundColor: 'yellow'}}
ref={ref => viewRefSuccess = ref}>
<Text>
Hello View Snap Shot
</Text>
</View>
However it will crash with the "Trying to resolve view with tag 'tagID' which doesn't exist"
if I remove the backgroundColor props.
<View ref={ref => viewRefSuccess = ref}>
<Text>
Hello View Snap Shot
</Text>
</View>
Any thought on why this is happening?
Thanks.
My app use surfaceview to display the video,and I want to take a screenshot to share to other people when i play the video, i have tried many ways,but did'n work,what i got is black screen, so I want to ask this program can be used to take a screenshot of surfaceview ? Any advice will be appreciated.
Im on RN 0.27.2 and I got it working just great with IOS, However android fails with import com.facebook.react.uimanager.UIBlock;
and anything that uses the UIBlock, Does android only work with versions of react-native that are react-native@>=0.30.0
?
This is what i get when running my script:
"file:///data/user/0/com.coach/cache/ReactNative-snapshot-image1317300113.png"
When i put it like this:
<Image source={{uri: uriAbove }} />
it shows nothing.
When i put it like this:
<Image source={require(uriAbove)} />
react-native crashes with error:
Unknown named module: 'file:///data/user/0/com.coach/cache/ReactNative-snapshot-image1317300113.png'
Any idea what I can do about it?
use with scrollview,can not capture without screen
Hi,
I successfully capture the view as png/jpeg in react-native in Android.
I captured the view as file and saved for later use. The view contain image and text. But the original view in the screen disappeared (become empty in the screen) after captured the view.
I want to display the same view (not captured image) even after captured the image. Any way to achieve this ? Please advise ASAP.
Please find attached the before view and after captured view (empty).
The shot image is blur, even though I set the quality to 1.0.
Is there anyway to get a high quality or clear image?
i mean if you save image into path: DCIM/Camera ,
the image file could find in [file manager],but not showed in system photo application
device info android
oppo r9
xiaomi 4 5
Simulator is effective to save, iphone will be prompted on the authority
Can anyone give me an example of how to implement the Refview?
I just put view there, and it throws an error 'ExceptionsManager.js:71 Unhandled JS Exception: findNodeHandle(...): Argument is not a component (type: function, keys: displayName,AccessibilityTraits,AccessibilityComponentType,forceTouchAvailable,propTypes)'
Many thanks,
Ian
So I upgraded to RN 0.40 and everything broke. So now I'm trying to go through each library I used and hopefully get it working again.
I upgraded to 1.6.0 and can't get the project to build, with errors like:
/MY_APP_LOCATION/node_modules/react-native-view-shot/ios/RNViewShot.m:31:16: Property 'uiManager' cannot be found in forward class object 'RCTBridge'
I npm install
the 1.6.0 and react-native unlink react-native-view-shot
ed then react-native link react-native-view-shot
ed and cleaned project in xCode but still not compiling. One of the errors is coming from this library as shown in the image above.
Any ideas on how to fix this please 🙏?
if i want to specifyc img to path "file:///storage/emulated/0/Tencent/MicroMsg/WeiXin",
i tryed to write like
`path:"file:///storage/emulated/0/Tencent/MicroMsg/WeiXin/qr.png" but failed ,
instead of writing into tmp
file,,why don't store image into persistent storage such as Documents
directory..?? after that image can be accessed with ~/Documents/filename
...
Part of my snapshot is an Image
, which is fading in, when the image is loaded and displayed the first time. When I take a snapshot, while the image is still not completely displayed, I get a grayed out image.
Is there a way to trigger the snapshot, when the View
is ready and rendered completely?
What I am currently doing is trigger the snapshot with onLayout
of the outer View
and a relatively long timer, that waits another second, before the snapshot is taken. But that is making my app less responsive and sometimes the image is still not there, when the snapshot fires. I tried onLoad
and onLayout
of the Image
, but those did not work any better.
Any Idea?
Thanks, Tim
When I load an image into a view and then use react-native-view-shot to create an image from that view the resolution seems to be doubled.
I don't think I'm doing anything weird...
Here is the function I'm using to take the image:
console.log('taking picture of size: ', width, height);
RNViewShot.takeSnapshot(this.refs['layout'], {
format: 'png',
quality: 0.8,
width,
height
})
.then(
uri => {
console.log('Image saved to', uri);
Image.getSize(uri, (width, height) => {
console.log(`Image dimensions: ${width}x${height}`);
});
},
error => console.error('Oops, snapshot failed', error)
);
}
And the output:
[PERF ASSETS] Loading image at size {3600, 3600}, which is larger than the screen size {750, 1334}
index.ios.js:21 taking picture of size: 3600 3600
index.ios.js:30 Image saved to /Users/chris/Library/Developer/CoreSimulator/Devices/A0EC9E9C-B184-46B8-80BE-DCCA88E4C699/data/Containers/Data/Application/2552626F-31AC-4F3D-86BF-12EFCC163100/tmp/ReactNative/DB9581E0-E465-460C-A3E9-FC904218C47E.png
index.ios.js:32 Image dimensions: 7200x7200
I got following error/rejection:
2016-11-12 13:43:43.339 [info][tid:com.facebook.react.JavaScript] 'Taking snapshot', true
Nov 12 13:43:43 rnSnapshooter[96767] <Error>: CGContextSaveGState: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable.
Nov 12 13:43:43 rnSnapshooter[96767] <Error>: CGContextRestoreGState: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable.
2016-11-12 13:43:43.380 [error][tid:com.facebook.react.JavaScript] 'Oops, snapshot failed', { [Error: Failed to capture view snapshot]
line: 3548,
column: 20,
sourceURL: 'http://localhost:8081/index.ios.bundle?platform=ios&dev=true&minify=false',
framesToPop: 1,
code: 'EUNSPECIFIED',
nativeStackIOS:
[ '0 rnSnapshooter 0x000000010a054ea6 RCTJSErrorFromCodeMessageAndNSError + 134',
'1 rnSnapshooter 0x0000000109fd4aa3 __41-[RCTModuleMethod processMethodSignature]_block_invoke_2.224 + 147',
'2 rnSnapshooter 0x000000010a0fb899 __54-[RNViewShot takeSnapshot:withOptions:resolve:reject:]_block_invoke + 1161',
'3 rnSnapshooter 0x000000010a08f4d8 __29-[RCTUIManager flushUIBlocks]_block_invoke + 792',
'4 libdispatch.dylib 0x000000010e57fe5d _dispatch_call_block_and_release + 12',
'5 libdispatch.dylib 0x000000010e5a049b _dispatch_client_callout + 8',
'6 libdispatch.dylib 0x000000010e5882af _dispatch_main_queue_callback_4CF + 1738',
'7 CoreFoundation 0x000000010b59bd09 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 9',
'8 CoreFoundation 0x000000010b55d2c9 __CFRunLoopRun + 2073',
'9 CoreFoundation 0x000000010b55c828 CFRunLoopRunSpecific + 488',
'10 GraphicsServices 0x000000011003cad2 GSEventRunModal + 161',
'11 UIKit 0x000000010cf59610 UIApplicationMain + 171',
'12 rnSnapshooter 0x0000000109fac8bf main + 111',
'13 libdyld.dylib 0x000000010e5d492d start + 1' ],
domain: 'RCTErrorDomain',
userInfo: null }
with following view to snapshot:
<View ref="root" style={{backgroundColor: 'yellow'}}>
<DemoApp/>
</View>
everything works with style={{flex:1,backgroundColor: 'yellow'}}
. Without the flex I can see DemoApp
but I don't see yellow background.
Feel free to close this issue if you don't want to handle such cases. Just wanted to document somewhere my troubles and how to "workaround" them if anyone would come to this problem.
Is there a any way for detect user manual snapshot ?
when i save image as base64, throw a error, and set result to 'data-uri' is same.
RN version: 0.36.1.
code:
RNViewShot.takeSnapshot(this.ref, { format: "png", quality: 0.8, result: 'base64', })
error:
'NSInvalidArgumentException', reason: '*** -[__NSPlaceholderArray initWithObjects:count:]: attempt to insert nil object from objects[0]'
*** First throw call stack:
(
0 CoreFoundation 0x0000000106df8d85 __exceptionPreprocess + 165
1 libobjc.A.dylib 0x000000010642bdeb objc_exception_throw + 48
2 CoreFoundation 0x0000000106cb1a52 -[__NSPlaceholderArray initWithObjects:count:] + 290
3 CoreFoundation 0x0000000106d0e0b4 +[NSArray arrayWithObjects:count:] + 52
4 mofang_app 0x0000000102908edf -[RCTPhotoLibraryImageLoader loadImageForURL:size:scale:resizeMode:progressHandler:partialLoadHandler:completionHandler:] + 447
5 mofang_app 0x0000000102a155d3 __118-[RCTImageLoader _loadImageOrDataWithURLRequest:size:scale:resizeMode:progressBlock:partialLoadBlock:completionBlock:]_block_invoke.191 + 355
6 libdispatch.dylib 0x0000000107edbd9d _dispatch_call_block_and_release + 12
7 libdispatch.dylib 0x0000000107efc3eb _dispatch_client_callout + 8
8 libdispatch.dylib 0x0000000107ee282c _dispatch_queue_drain + 2215
9 libdispatch.dylib 0x0000000107ee1d4d _dispatch_queue_invoke + 601
10 libdispatch.dylib 0x0000000107ee4996 _dispatch_root_queue_drain + 1420
11 libdispatch.dylib 0x0000000107ee4405 _dispatch_worker_thread3 + 111
12 libsystem_pthread.dylib 0x00000001082394de _pthread_wqthread + 1129
13 libsystem_pthread.dylib 0x0000000108237341 start_wqthread + 13
)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb)
I'm integrating react-native into existing ios, can't find any .podspec file.
Can anyone tell how to install this lib?
Hi,
Thanks for this good plugin.
Is there any way for this plugin to support the ReactNativeART library? Or do you have any plans to add this feature?
I would love to use it with a components like Surface, Shape, Path from ReactNativeART.
Thanks for advance.
Hey so I'm having this issue. I can't seem to figure out if this is something that I'm doing wrong or an actual issue with the package. Please help!
The code:
snapshot = view => () => takeSnapshot(this.refs[view], { format: "jpeg", quality: 0.8 }) .then( uri => console.log("Image saved to", uri), error => console.error("Oops, snapshot failed", error) )
and
<View ref = "main"> <Button rounded danger style = {{ width: 55, height: 55 }} onPress = {this.snapshot("main")} > test </Button> </View>
following up of #66 (comment) / #62 (comment)
need to deprecate "path" and release a major that drop it.
for moving files, use react-native-fs or CameraRoll.saveToCameraRoll
I am using simple code to take snapshots:
takeSnapshot(view)
.then(uri => { ...
works fine on IOS but fails on android Attempt to invoke ... hasKey ... on a null object reference
and pointung to line 49.
From the documentation itself it is not 100% clear if options are mandatory however flow definition shows that they should be https://github.com/gre/react-native-view-shot/blob/master/index.js#L9
just the reason we (most of the time!) needs to do collapsable={false}
on Android, and sometimes even needs to wrap a parent <View collapsable={false}>
(e.g. WebView) makes me think maybe we should hide that from the lib user ( note https://github.com/gre/react-native-view-shot#specific-to-android-implementation ).
Maybe the library should (only?) be available through a wrapper Component.
<Snapshotable ref="snap"> ... </Snapshotable>
snap.capture().then(...
WDYT?
one downside is introducing a <View>
wrapping changes the hierarchy.
Hi there, first thing thanks very much for your hard work on this project :)
I would like to know if there is a way to take a snapshot without passing the ref, and i'm asking this because to get the ref (correct me if i'm wrong) you need to render the element, and that's my problem, i have to create images of about 80 views. as you understand this is a performance killer.
If you believe it's possible to make this in some way.
i'm very interesting to know your toughs's on this one.
in the native code side i was think something like this:
Pass to bridge Component and props-->In the Native side call react-native method to create the View in the background--> create a image of the view --> return path
All this procedure made with multi threading support.
Attention, i never create a native module for react-native, it's probably that i said something stupid above.
This issue is to know if Its possible to do, if you can do it, and if you can't , if you could assist me to do it.
if i can capture user screen capture, it will be perfect.
thanks!
Hi
I integrated rnvs few weeks back and it was working perfectly then. Suddenly I am seeing error whenever I am trying to capture screenshot.
Here is my code for taking screenshot.
takeScreenShot(){
RNViewShot.takeSnapshot(this.refs.screenshot, {
format: "jpeg",
quality: 0.8
})
.then(
uri => this.saveScreenshot(uri),
error => console.error("Oops, snapshot failed", error)
);
}
This is the error I am getting whenever calling takeScreenShot function.
2016-12-06 14:34:22.635 [error][tid:com.facebook.react.JavaScript] 'Oops, snapshot failed', { [Error: findNodeHandle failed to resolve view=undefined]
line: 525,
column: 133,
sourceURL: 'file:///Users/ABC/Library/Developer/CoreSimulator/Devices/17A973BC-5639-4C55-B52E-D7FE972F2651/data/Containers/Bundle/Application/87DDE253-950F-4BB2-8F4C-C8C468862DD2/MYAPP.app/main.jsbundle' }
This is the error in xcode logs
RCTBridge required dispatch_sync to load RCTAccessibilityManager. This may lead to deadlocks
Is it possible to prevent the snapshot screen flash on IOS?
Hi, maybe this is more a general purpose Android question, but I thought perhaps you could help. Since the uri that is generated for a snapshot only exists in the app cache, passing its uri to a share intent always fails. As soon as I change it to a file saved on external storage, it works. Obviously I'd like to avoid doing this, so I'm looking for other ways to achieve this. More than willing to submit a PR. Thanks!
EDIT: My proposal would be an option like {saveToDisk: true} being passed in which would cause the module to call something like createPermanentFile
instead of createTempFile
, but my native Android fu is limited, so there's probably a better way.
no error showed,and no picture is generated
How can I custom size of Image file after take snapshot? I tested on iPhone 6 simulator, file result only have 750px width.
Example: I wanna result file have 2048x2048 px.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.