Auto scale image height with React Native

后端 未结 14 1175
陌清茗
陌清茗 2020-12-04 23:19

In my React Native app, I am fetching images from an API with unknown dimensions. How do I auto scale the height if I know my desired width?

Example:

I set t

相关标签:
14条回答
  • 2020-12-04 23:53

    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.

    0 讨论(0)
  • 2020-12-04 23:54

    Have a look at this library react-native-scalable-image. It does exactly what you are asking for.

    import React from 'react';
    import { Dimensions } from 'react-native';
    import Image from 'react-native-scalable-image';
    
    const image = (
       <Image
           width={Dimensions.get('window').width} // height will be calculated automatically
           source={{uri: '<image uri>'}}
       />
    );
    
    0 讨论(0)
  • 2020-12-04 23:54

    Here's a gist for a pretty simple solution that leverages @Haitao Li's proposal to use aspectRatio:

    https://gist.github.com/tpraxl/02dc4bfcfa301340d26a0bf2140cd8b9

    No magic and no calculations necessary. Pure "CSS" if you know the original image's dimensions.

    0 讨论(0)
  • 2020-12-04 23:56

    Based on @TheJizel's idea, I cooked up something using the aspectRatio style property. The following class works when the width is set, but height is omitted. This also works with percentages as width.

    import React from "react";
    import { Image } from "react-native";
    
    export default class ScaledImage extends React.Component {
    
      state = {
        aspectRatio: 0
      }
    
      setAspectRatio(ratio) {
        this.setState({
          aspectRatio: ratio
        });
      }
    
      componentWillMount() {
        if (Array.isArray(this.props.source)) {
          console.warn("ScaledImage received an array as source instead of local file resource or ImageURISource.")
        } else if(typeof this.props.source === "number") {
          // Resolve local file resource
          const resolved = Image.resolveAssetSource(this.props.source);
    
          // We assume 100% width, so we set the aspect ratio we want for it's height
          this.setAspectRatio(resolved.width / resolved.height);
    
        } else if (this.props.source.uri) {
          // Resolve remote resource
          Image.getSize(this.props.source.uri, (width, height) => {
             this.setAspectRatio( width / height);
          }, (err) => {
            console.error(err);
          });
    
        } else {
          console.warn("ScaledImage did not receive a valid source uri.");
        }
      }
    
      render() {
        if(!this.state.aspectRatio) return null;
    
        const props = {
          ...this.props,
          style: [this.props.style, {
            aspectRatio: this.state.aspectRatio
          }]
        };
    
        return (
          <Image {...props} />
        )
      }
    }
    

    Usage:

    <ScaledImage source={{ uri: "<URI HERE>" }} style={{ width: "100%" }} />
    
    0 讨论(0)
  • 2020-12-04 23:58

    First try this and see if it works for you: https://github.com/facebook/react-native/commit/5850165795c54b8d5de7bef9f69f6fe6b1b4763d

    If it doesn't, then you can implement your own image component. But instead of taking width as prop, you override onLayout method which gives you desired width so that you can calculate the height. This works better if you don't know the width and want RN to do the layout for you. The drawback is onLayout is called after one pass of layout and rendering. So you might notice your components moving around a bit.

    0 讨论(0)
  • 2020-12-05 00:03

    This one worked for me in expo

    <Image style={{flex:1,width:null,height:null }} resizeMode={'contain'}  source={{uri: 'http://134.209.40.60/meApunto/1567655610795_1944474896.png'}}></Image>
    

    https://forums.expo.io/t/how-to-fit-a-big-image-into-a-fixed-container-without-resizemode-help/27639

    0 讨论(0)
提交回复
热议问题