I'm getting nothing but errors from the ReactNative CameraRoll's saveImageWithTag
function. Saving a local image with something like:
CameraRoll.saveImageWithTag('./path/to/myimage.png');
.then(res => console.log(res))
.catch(err => console.log(err));
gives me the error:
Error: The file “myimage.png” couldn’t be opened because there is no such file.(…)
./path/to/myimage.png
in this case is the path I'd use to require
an image for an Image
source. What should the full path be for a local image be? Do I need to store them differently to make them accessible?
0. Short answer
Use RNFS to locate the local image.
1. For your title 'Save remote image to camera roll in React Native'
The keyword is remote
.
Before using CameraRoll, we should link the library first.
Then, I create one Image
and one Button
:
render: function() {
return (
<View style={styles.container}>
<Image ref="logoImage"
style={{ height:50, width: 50 }}
source={{uri: 'http://facebook.github.io/react/img/logo_og.png'}}
/>
<TouchableHighlight style={styles.button} onPress={this._handlePressImage} underlayColor='#99d9f4'>
<Text style={styles.buttonText}>Save Image</Text>
</TouchableHighlight>
</View>
);
},
When I press the button, the program will save the image to camera roll:
_handlePressImage: function() {
console.log('_handlePressImage.');
var uri = this.refs.logoImage.props.source;
console.log(uri);
CameraRoll.saveImageWithTag(uri, function(result) {
console.log(result);
}, function(error) {
console.log(error);
});
},
React Native
warns me that the API is deprecated, just use promise
instead:
var promise = CameraRoll.saveImageWithTag(uri);
promise.then(function(result) {
console.log('save succeeded ' + result);
}).catch(function(error) {
console.log('save failed ' + error);
});
Now, we can see the logo image in our camera roll.
2. For your real problem in your content
Despite your title says remote
, your code uses the local
path.
Give the path './path/to/myimage.png'
, I assume that the image path is relative to the .js
file. That is, your image is not relative to the final running app, so it can not find the image file.
Now change the Image
to use local file:
<Image ref="logoImage"
style={{ height:50, width: 50 }}
source={require('./logo_og.png')}
/>
and save the image like this:
var promise = CameraRoll.saveImageWithTag('./logo_og.png');
which results in:
Because CameraRoll API
is corresponding to the Native Component
, which belongs to the final running app, not the javascript.
3. Use RNFS to save local images
First run the command below:
npm install react-native-fs --save
and then link the library.
After Putting the image under Library/Caches
:
we can save the local image:
var cacheImagePath = RNFS.CachesDirectoryPath+"/logo_og.png";
console.log(cacheImagePath);
var promise = CameraRoll.saveImageWithTag(cacheImagePath);
promise.then(function(result) {
console.log('save succeeded ' + result);
}).catch(function(error) {
console.log('save failed ' + error);
});
Thanks.
Use this saveToCameraRoll method.
import { CameraRoll } from 'react-native';
CameraRoll.saveToCameraRoll(url)
.then(alert('Done', 'Photo added to camera roll!'))
.catch(err => console.log('err:', err))
}
The user's permission is required in order to access the Camera Roll on devices running iOS 10 or later. Add the NSPhotoLibraryUsageDescription key in your Info.plist with a string that describes how your app will use this data. This key will appear as Privacy - Photo Library Usage Description in Xcode. If you are targeting devices running iOS 11 or later, you will also need to add the NSPhotoLibraryAddUsageDescription key in your Info.plist.