round image in react native without zoom effect - react-native

I have the following code :
<Image
style={styles.avatar}
source={{
uri: `${BASE_URL}/avatars/${userAvatar}`,
}}
resizeMode="cover"
/>
and for styling :
avatar: {
width: 70,
height: 70,
borderRadius: 50,
marginRight: "5%",
},
That code works and displays the image in a circle shape.
The problem is that the image is "zoomed" more or less depending on the difference concerning is native height and width.
For instance, if I use an image like this one :
https://www.artmajeur.com/medias/hd/a/n/anib/artwork/12741944_humboldt-pinguin-1.jpg
I can't see the head of the pinguin.
If I use the resizeMode="contain" instead of cover, I am not able to get a circle shape.
Plus, I have read that android required the "cover" value.
How can I do to see the whole image (more or less) in a circle shape ?

If you want the maintain the dimensions of avatar and see the whole image as well, then you could use resizeMode="stretch".
<Image
style={styles.avatar}
source={{
uri: `${BASE_URL}/avatars/${userAvatar}`,
}}
resizeMode="stretch"
/>
Depending on the image, this might not look appealing. However, unless you know exactly what images you need to display, there is no way to know which parts of the images you want to zoom in. This is the reason why most applications that allow for example an avatar image require the user to select the section of the image if the aspect ration does not match.
Notice, that the image container still has the circular shape if using a different resizeMode. However, the image itself will not have this shape. We can test this by setting a background color.

Related

React native image have bad quality

I used hd image but my image have bad quality (large and pixelated) whit this code:
<Image source={require('../../assets/images/logo.png')}/>
When i resizeMode: 'center' the quality is good, but image is small.
<Image style={{resizeMode: 'center'}}
source={require('../../assets/images/logo.png')}/>
My actual image size is:
153px x 43px
You know the dimensions of the image. So set style={{ resizeMode:'stretch', width:XXXX, height:XXXX }} where width and height maintain aspect ratio. Using stretch has the added benefit of the image's View container being perfectly fit to it, so you can position the element perfectly.

Nativebase : change thumbnail default size

I can't change the default size of the thumbnail from NativeBase. I can display the default circle, which is the small and the large one, but I want to display a bigger circle than the default size. Here's my code for the thumbnail :
<Thumbnail size={200} style={{margin: 30}} source={require('../../../public/images/profile/yellow.jpg')} />
The props size doesn't work, the thumbnail remains small.
My NativeBase version : 2.3.5
Native Base Component doesn't have a size props, you should add width and height, and one more thing you shouldn't forget please add borderRadius divided by 2 to ensure the shape is retain Circle
<Thumbnail style={{width: 30, height: 30, borderRadius: 30/2}} source={require('../../../public/images/profile/yellow.jpg')} />
You can simply increase the Thumbnail size by using this trick. Just take the property of scale with <Thumbnail/>.
Just copy-paste the below code in your app
<Thumbnail
scaleX={3} scaleY={3} style={{margin: 30}}
source={require('../../../public/images/profile/yellow.jpg')}/>
You can change the scale values as per your need. Let me know if this fixes your issue.
The Thumbnail component from NativeBase doesn't have the size attribute. Try to set width and height properties of the style attribute
<Thumbnail style={{width: 100, height: 100, margin: 30}} source={require('../../../public/images/profile/yellow.jpg')} />
NativeBase Thumbnail component comes with small and large props for size. You can also set width and height to have image with other dimensions

React-Native Image resizeMode contain doesn't work on Android

I am using below lines of code to display an image in full window in my application
<View style={{flex: 1, alignItems: 'center', justifyContent: 'center'}}>
<Image source={avatarSource}
style={{width, height}}
resizeMode={Image.resizeMode.contain} />
</View>
The avatarSource is a base64 encoded image string. When the app starts, only thumbnails are downloaded for all the images and if the user clicks on the avatar, the full image is shown similar to Whatsapp. If the full image is not present, initially the thumbnail is loaded on the full screen and the full image is downloaded from the server and then once the full image is downloaded, the avatarSource is updated and as a result, the full image is shown in the view. This thing works seamlessly on iOS but on Android, once the full image is downloaded, the Image component updates itself but doesn't render anything and I just see a white screen. If I remove the resizeMode from the Image, then the Image component updates correctly but I think the default resizeMode is cover due to which some parts of the image are clipped.
If you have come across this problem or/and have some solution in mind, please share. Thanks in advance!
use resizeMode: "contain" as part of the style, so:
style={{width, height, resizeMode: "contain"}}

Image 'contain' resizeMode not working in react native

I am using React Native on a real Android device.
When creating a really simple app with just the following render function on the main app component...
render() {
<Image
source={{uri:'http://resizing.flixster.com/DeLpPTAwX3O2LszOpeaMHjbzuAw=/53x77/dkpu1ddg7pbsk.cloudfront.net/movie/11/16/47/11164719_ori.jpg'}}
style={
{
flex: 1,
resizeMode: 'contain',
backgroundColor: 'yellow'
}
} />
}
I get the following result on my device:
As you can see the whole background is yellow so that tells us the image element is taking the whole screen size indeed. But it is just rendered wrong.
The 'cover' resizeMode does work as expected (and so does the 'stretch' mode).
It is the 'contain' mode that is not working (the most important one from my point of view).
The problem gets even worse when placing the image on a ListView since the image does not even show.
UPDATE 1
As Frederick points out, 'contain' only works when the image is larger than the container size. So how can we make the image take the whole container size while keeping its aspect ratio?
Percentages are not supported yet by styles in React, and I don't know how to get the image width and height properties once the image is loaded. None of the events associated with the Image component provide that info.
UPDATE 2
Good news. I am now using React Native v0.24.1 and it seems the image 'contain' mode now works as expected, even when the actual image size is smaller than its container.
zvona's solution is good (although you need to bear in mind that onLayout will give you the image view size the image is rendered in, but NOT the actual image size being loaded). As for now, I don't know of any way to find out the actual image size (let's suppose you are retrieving the image from a network resource and you don't know the size, which could be very important if you want to calculate its aspect ratio).
This is the trick:
render() {
return (
<Image
style={{ flex: 1, height: undefined, width: undefined }}
source={require("../../resource/image/bg_splash.jpg")}
resizeMode="contain"
/>
);
}
This is the latest solution:
Image.resizeMode.contain is not working with latest version of react native so i use it like this:
import ImageResizeMode from 'react-native/Libraries/Image/ImageResizeMode'
<Image source={image} resizeMode={ImageResizeMode.contain} />
This is what worked for me with the latest react-native 0.37:
<Image source={require('../images/my-image.png')} resizeMode={Image.resizeMode.center} />
Answering the updated part of the question. You can get the image size for external images using Image.getSize.
For local images, a not so documented way to figure out the size and thereby calculate the aspect ratio is using resolveAssetSource which is a react-native module (no need for an external library):
let resolveAssetSource = require('resolveAssetSource')
let { width, height } = resolveAssetSource(image_source)
let aspectRatio = width / height
My answer to UPDATED part of the question:
<Image source={{uri:'...'}} onLayout={this.onImageLayout} />
where:
onImageLayout: function(data){
console.log('layout', data.nativeEvent.layout);
}
These should be proportioned to device width + height, which you get with:
const {
Dimensions,
.
.
.
} = React;
const windowWidth = Dimensions.get('window').width;
const windowHeight = Dimensions.get('window').height;
And if you want to get width/height as percentages in styles, you just define e.g.:
const styles = StyleSheet.create({
image: {
width: windowWidth * 0.75,
height: windowHeight * 0.33
}
});
"Contain" only resizes your image when the image size is larger than the container you're trying to fit it in. In this case, your container is the full screen. The image you're loading via the URL is way smaller, since it's only 53 by 77 pixels. So it won't resize.
I think "cover" should do what you're trying to achieve. However, due to the size the image, it won't look very nice when it is magnified like that.
Made an example here: https://rnplay.org/apps/X5eMEw
Adding the aspect ratio worked for me:
<Image
source={item.imageUrl && item.imageUrl != '' ? { uri: item.imageUrl } : require('../../assets/images/no-image-icon-15.png')}
style={{
flex: 1,
aspectRatio: 1.5,
height: undefined,
width: undefined
}}
resizeMode="contain"
/>
I will suggest you a simple solution to apply if it's convenient for you.
use "ImageBackground" component of react-native.
so your code will become something like this:
<ImageBackground
source={{uri:'http://resizing.flixster.com/DeLpPTAwX3O2LszOpeaMHjbzuAw=/53x77/dkpu1ddg7pbsk.cloudfront.net/movie/11/16/47/11164719_ori.jpg'}}
style={{flex: 1}} />
In your particular case you are apparently trying to cover whole screen with the image so this solution is exactly for that purpose. However most of the time it works in other cases as well where you want to fit the image properly in its view.

Add content in bounce margin of ScrollView in React Native?

In my app I'm using <ScrollView /> to view pages of a book scrolling horizontally. When a user gets to the end of the <ScrollView /> there is a bounce that shows a white area to the right that is only visible if the user drags the last page to the left. I want to add some text there that says "The End" vertically. How can I add content to the right of the <ScrollView /> in the bounce area?
I ALMOST figured it out. This is close but shows up in the right side of the last page but not off the page on the right in the bounce area. I want it to show up "to the right of the page" not "on the right side of the page." Any other ideas?
Create a <View style={styles.end} /> with this style:
theEnd: {
position: 'absolute',
top: 0,
right: 0,
width: 100,
height: 768, // Device height
alignItems: 'center',
}
Place it right before the <ScrollView /> and put whatever you want to show inside of the View component with the "theEnd" style.
This probably doesn't apply to your content, but I had the same situation except with a large image for the ScrollView content. I wanted both horizontal and vertical scrolling, where the edge of the image would show up only in the bounce margin. I figured out that the scale transformation works great for this:
<ScrollView horizontal={true}>
<Image
source={require('./img/map.jpg')}
style={{transform: [{scale: 1.1}]}}
/>
</ScrollView>
So the image takes up 110% of the height and width of its box (which is then inside a yet smaller ScrollView).
EDIT: FYI, after testing, discovered this only works on iOS, not Android. (Android won't allow vertical scrolling if you set horizontal to true, and also I think it didn't render the parts outside of the normal viewing area, so the bounce margin was empty.)
there is a prop for this called contentContainerStyle
<ScrollView
horizontal={true}
contentContainerStyle={{
paddingLeft: 25,
paddingRight: 25,
}}>
*** CONTENT ***
</ScrollView>