Save image from URL to device with React Native - android

Hi as title suggests I need to save images to Android device from my CDN.
I am building app with React Native, and what I've done is that:
fetch('https://server.com/images.json').then((json) => console.log(json))
Which returns json:
{images: ["cdn.server.com/image1.jpg", "cdn.server.com/image2.jpg"]}
And now I really don't know what to do to save images to my device, because then I need to use them to open Instagram Intent (https://www.instagram.com/developer/mobile-sharing/android-intents/) and it only works if image is saved to device.
Any ideas?

I don't know react can using Java code.
I offen using this code to get image from url.
String imageCDN = json.getString("images");
ImageLoader imageLoader = new ImageLoader(this);
ImageView imgflag = (ImageView) findViewById(R.id.flag);
imageLoader.DisplayImage(imageCDN, imgflag);
But you should read this tutorial
At this code:
renderMovie(movie) {
return (
<View style={styles.container}>
<Image
source={{uri: movie.posters.thumbnail}}
style={styles.thumbnail}
/>
<View style={styles.rightContainer}>
<Text style={styles.title}>{movie.title}</Text>
<Text style={styles.year}>{movie.year}</Text>
</View>
</View>
);
}
You don't need to save image because memory leak, using ListView to clone all image in DataSource.

Related

React-Native Disable Image Cache on Android

i am trying to use a random image generator for a demo app i am creating.
i have tried the endpoints:
http://thecatapi.com/api/images/get?format=src&type=gif&size=small
http://junglebiscuit.com/images/random/rand_image.pl
but when i add a list of images to my page with:
<View>
<Image
source={{ uri: 'http://thecatapi.com/api/images/get?format=src&type=gif&size=small' }}
style={{ width: 100, height: 100 }}
/>
<Image
source={{ uri: 'http://thecatapi.com/api/images/get?format=src&type=gif&size=small' }}
style={{ width: 100, height: 100 }}
/>
<Image
source={{ uri: 'http://thecatapi.com/api/images/get?format=src&type=gif&size=small' }}
style={{ width: 100, height: 100 }}
/>
</View>
the expectation is that for each Image component, a different image would be displayed. strangly, this does not work on Android. it seems that the image or url is being cached somewhere so when the image is rendered again with the same URI, the same image is displayed.
i have tried the same application on IOS (the app is created using react native expo.io). the image are different as expected on IOS, it it seems to be a problem specific to Android.
is there a way to prevent android from cacheing the image and display a different image every time the Image component is rendered?
In 2020 it`s still an issue in react native (as Dishant Walia mentioned). Now best solution from github is:
add a query string after url, works for both platform
<Image
style={styles.drawerAccountImg}
source={uri: this.state.photoURL + '?' + new Date()}
/>
Somehow you have to add random string to reload image with same uri. I have fixed the same issue by adding random string in image url.
Follow this comment for more information
React native image issue

Dynamically set uri of a react native <Image />

I am trying to build a FlatList which will have an icon on the left (pretty much like any Contacts app) and I'm trying to dynamically load an image based on the name of the element
<Image
style={styles.image}
source={{uri: `./assets/${this.props.name}.png`}}
/>
Which is not allowed by React Native, as stated by their Image docs.
Are there any workaround?
if your image is in your project (eg assets folder) you can not create dynamically, the most you can do is an array to select, like this:
var icons = [ require('image!my-icon-active') ,require('image!my-icon-inactive')];
<Image
style={styles.image}
source={icons[1]}
/>
but you can save the images in a folder and read from your local storage using 'file://' or 'data://' like you are reading from Web, that can be dinamically link:
let uri = 'file://'+this.state.pathToResources+'/'+href;
<Image
style={{width: 400, height: 400}}
resizeMode='contain'
source={{uri}}
/>
You can use the lib
https://github.com/itinance/react-native-fs
for you ready from local disk of your smartphone, but you need manage the height e width.
For more read https://facebook.github.io/react-native/docs/images.html#uri-data-images
Just create a variable in the state:
constructor(props) {
super(props);
this.state = {
imgUri: ""
}
}
...
<Image
style={styles.image}
source={{uri: this.state.uri}}/>
Update the uri by calling this.setState({imgUri: "foobar"})

Convert from image to url in react native

may I know how to change the image to the URL or link in react native? Below are the screenshot and the code:
The image can display at here but I want to make it become a link in attachment field here
Example of the URL or link: "http://exampleimage.jpg"
Here is the code
<TextInput
onChangeText={(attachment) => {
this.setState({attachment})
}}
placeholder="Attachment"
style={styles.input}
/>
{img}
<TouchableOpacity onPress={this.show.bind(this)}>
<Icon name="device-camera" size={20} color="black"/>
</TouchableOpacity>
...
show(){
pick((source, data) => this.setState({avatarSource: source, data: data}));}
I use the react-native-image-picker to do it. Please advise on how to do it. Any help will be appreciated. Thank you.
Create let variable in render block with.
Assign Image Url to let variable using uri .
Add Image tag in render’s return block.
Add Source attribute in Image tag and Assign Let variable name to it.
Add inline style to Image tag.

React Native LruCache: Does it cache images from image urls

Basically, I am making an API call to get some kind of response back. In this response, there is some field like socialImageUrl that points to a URL string that references an image. There is other data there besides the URL. I am caching that entire response.
So I turn off wifi and LTE, and I checked that I had no internet connection by doing stuff on the browser. I go back into my app and I trigger my LruCache and retrieved the cached response (I know I got it because of logging) and I use that response to render my page.
What I expected: I would see all the data that I cached on the page but anything that used the image URLs will give out some erroneous image or maybe the page doesn't even load at all because there is some error with that image URL seeing as it can't access the internet
What actually happens: I see all of the data I cached and I also see the images
Any clue to what is going on? I'm not doing any image caching as far as I know. I am using react-native's vanilla Image JSX component. I am also on Android.
I was also in this situation ones, sadly React-Native docs are not extensive for now.
The Android implementation of Image component has by default caching enabled for images of low size < 500 KB (the max size is not documented but you can just try images of varied size to check and this size could change in the future).
Note: Even in IOS the image's will be cached by default when using the Image component.
If I had to guess, lru cache does not support caching binary data like an image file.
If you need advanced <Image> performance caching or for the remote image to be permanently stored to local disk for offline app use you can use my higher order component module that upgrades native <Image>
React Native Image Cache HOC
Tl;DR Code Example:
import imageCacheHoc from 'react-native-image-cache-hoc';
const CacheableImage = imageCacheHoc(Image);
export default class App extends Component<{}> {
render() {
return (
<View style={styles.container}>
<Text style={styles.welcome}>Welcome to React Native!</Text>
<CacheableImage style={styles.image} source={{uri: 'https://i.redd.it/rc29s4bz61uz.png'}} />
<CacheableImage style={styles.image} source={{uri: 'https://i.redd.it/hhhim0kc5swz.jpg'}} permanent={true} />
</View>
);
}
}
The first image will be cached until the total local cache grows past 15 MB (by default) then cached images are deleted oldest first until total cache is below 15 MB again.
The second image will be stored to local disk permanently. People use this as a drop in replacement for shipping static image files with your app, but you could use it so that your app displays image content even when user is offline.
If you need to grab all the image files from the network up front (before the <CacheableImage> is rendered by react native) then just use the following CacheableImage static method to pre-fetch the files:
import imageCacheHoc from 'react-native-image-cache-hoc';
const CacheableImage = imageCacheHoc(Image);
CacheableImage.cacheFile('https://i.redd.it/hhhim0kc5swz.jpg', true)
.then( localFileInfo => {
console.log(localFileInfo);
// Console log outputs:
//{
// url: 'https://i.redd.it/rc29s4bz61uz.png',
// cacheType: 'permanent',
// localFilePath: '/this/is/absolute/path/to/file.jpg'
//}
});

React Native: How to import local image with dynamic name

I have about 100 heroes' image on local that need to import into the listview. This is my hero.js
renderRow(hero) {
return (
<View>
<View style={styles.container}>
<Image
source={require('./img/hero/'+hero.img+'.jpg')}
style={styles.thumbnail} />
<View style={styles.rightContainer}>
<Text style={styles.title}>{hero.name}</Text>
</View>
</View>
<View style={styles.separator} />
</View>
);
After some research I know require won't allow dynamic name. I also tried uri, no error but no image either.
{{uri: './img/hero/'+hero.img+'.jpg'}}
My folder structure is like this:
Project
index.ios.js
hero.js
img
hero
What is the best way to handle this, I don't want to put images on the network.
sahrens said the following on this forum
We intentionally don't support dynamically generated image names because it makes it very hard to manage assets over time, just like how you wouldn't want to do
It looks like it can be done via uri but it will require a bit of work. You will need to add your images in xcode assets and for android under res/drawable.
Then you can get your image with <Image source={{ uri: "image" + "name" }} />
I solved this issue in one way, just post my answer here in case others interesting on how to deal with this.
I wrote a php script to read all images in my hero folder and print out in this format:
heroName: require ('./img/hero/heroName.jpg')
<?php
$dir = "./img/hero";
// Open a known directory, and proceed to read its contents
if (is_dir($dir)) {
if ($dh = opendir($dir)) {
$images = array();
while (($file = readdir($dh)) !== false) {
$keyName = str_replace(".jpg","",$file);
print "$keyName: require('./img/hero/$file'),". "<br />";
}
closedir($dh);
}
}
?>
Then I copy the result, paste into a js file and store as object like this:
export default heroList = {
name1: require('./img/hero/name1.jpg'),
name2: require('./img/hero/name2.jpg'),
etc....
}
Finally in my hero.js file:
import heroList from './heroList';
....
source={heroList[heroName]}

Categories

Resources