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>
    )
}