Auto scale image height with React Native
Solution 1:
Try this:
import React, { Component, PropTypes } from "react";
import { Image } from "react-native";
export default class ScaledImage extends Component {
constructor(props) {
super(props);
this.state = { source: { uri: this.props.uri } };
}
componentWillMount() {
Image.getSize(this.props.uri, (width, height) => {
if (this.props.width && !this.props.height) {
this.setState({
width: this.props.width,
height: height * (this.props.width / width)
});
} else if (!this.props.width && this.props.height) {
this.setState({
width: width * (this.props.height / height),
height: this.props.height
});
} else {
this.setState({ width: width, height: height });
}
});
}
render() {
return (
<Image
source={this.state.source}
style={{ height: this.state.height, width: this.state.width }}
/>
);
}
}
ScaledImage.propTypes = {
uri: PropTypes.string.isRequired,
width: PropTypes.number,
height: PropTypes.number
};
I'm passing the URL as a prop called uri
. You can specify your width
prop as Dimensions.get('window').width
and that should cover it.
Note that this will also work if you know what you want to set the height to and you need to resize the width to maintain the ratio. In that case, you would specify the height
prop instead of the width
one.
Solution 2:
There is a property resizeMode set it to 'contain'
Example:
<Image
source={require('./local_path_to/your_image.png')}
style={{ width: 30 }}
resizeMode="contain"
/>
Source: https://facebook.github.io/react-native/docs/image#resizemode
Edit: The above solution is working fine for me, the resizeMode property is not deprecated and I couldn't find any indications that they are planning to do so. If for some reason the the above solution doesn't work for you, you can calculate the height yourself. Here is an axample:
const Demo = () => {
const scaleHeight = ({ source, desiredWidth }) => {
const { width, height } = Image.resolveAssetSource(source)
return desiredWidth / width * height
}
const imageSource = './local_image.png'
const imageWidth = 150
const imageHeigh = scaleHeight({
source: require(imageSource),
desiredWidth: imageWidth
})
return (
<View style={{
display: 'flex',
flex: 1,
alignItems: 'center',
justifyContent: 'center'
}}>
<Image
source={require(imageSource)}
style={{
borderWidth: 1,
width: imageWidth,
height: imageHeigh
}}
/>
</View>
)
}
The above solution works only for local images. Here is how to do the same for remote images:
const RemoteImage = ({uri, desiredWidth}) => {
const [desiredHeight, setDesiredHeight] = React.useState(0)
Image.getSize(uri, (width, height) => {
setDesiredHeight(desiredWidth / width * height)
})
return (
<Image
source={{uri}}
style={{
borderWidth: 1,
width: desiredWidth,
height: desiredHeight
}}
/>
)
}
const Demo = () => {
return (
<View style={{
flex: 1,
alignItems: 'center',
justifyContent: 'center'
}}>
<RemoteImage
uri="https://via.placeholder.com/350x150"
desiredWidth={200}
/>
</View>
)
}