使用React Native自动缩放图像高度

plm*_*k61 42 react-native

在我的React Native应用程序中,我从具有未知维度的API中获取图像.如果我知道所需宽度,如何自动缩放高度?

例:

我将宽度设置为Dimensions.get('window').width.如何设置高度并保持相同的比例?

export default class MyComponent extends Component {
  constructor(props) {
    super(props)
    this.state = {
      imgUrl: 'http://someimg.com/coolstuff.jpg'
    }
  }

  componentDidMount() {
    // sets the image url to state
    this.props.getImageFromAPi()
  }

  render() {
    return (
      <View>
        <Image 
          source={uri: this.state.imgUrl}
          style={styles.myImg}
        />
        <Text>Some description</Text>
      </View>
    )
  }
}

const styles = StyleSheet.create(
  myImg: {
    width: Dimensions.get('window').width,
    height: >>>???what goes here???<<<
  }
)
Run Code Online (Sandbox Code Playgroud)

The*_*zel 43

试试这个:

 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
};
Run Code Online (Sandbox Code Playgroud)

我正在传递URL作为一个名为的道具uri.你可以指定你的width道具Dimensions.get('window').width,它应该涵盖它.

请注意,如果您知道要将高度设置为什么,并且需要调整宽度以保持比率,这也将起作用.在这种情况下,您将指定height支柱而不是支柱width.


Ned*_*rov 16

有一个属性resizeMode设置为“ contain”

例:

<Image
    source={require('./local_path_to/your_image.png')}
    style={{ width: 30 }}
    resizeMode="contain"
 />
Run Code Online (Sandbox Code Playgroud)

来源:https//facebook.github.io/react-native/docs/image#resizemode

  • 此解决方案不适用于“ expo”:“ ^ 32.0.0”,“ react”:“ 16.5.0”,“ react-native”:“ https://github.com/expo/react-native/archive/sdk -32.0.0.tar.gz”,仅设置高度有效,但仅在样式中设置宽度会产生空白图像。 (5认同)
  • 然而,它确实会自动缩放图像以适应定义的尺寸,这可以帮助通过一些思考解决上述问题 - 当然帮助我处理未知尺寸的图像。 (2认同)

Iho*_*nko 8

看看这个库react-native-scalable-image。它完全符合您的要求。

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>'}}
   />
);
Run Code Online (Sandbox Code Playgroud)

  • 刚刚尝试使用这个~2022 年,它已经 2 年没有更新了,这意味着依赖关系不再解析最新的 React 17x (3认同)

小智 6

我创建了一个计算图像纵横比的钩子:

function useImageAspectRatio(imageUrl) {
  const [aspectRatio, setAspectRatio] = useState(1);

  useEffect(() => {
    if (!imageUrl) {
      return;
    }

    let isValid = true;
    Image.getSize(imageUrl, (width, height) => {
      if (isValid) {
        setAspectRatio(width / height);
      }
    });

    return () => {
      isValid = false;
    };
  }, [imageUrl]);

  return aspectRatio;
}
Run Code Online (Sandbox Code Playgroud)

这样,您可以仅设置宽度或高度的一个值,并自动计算另一个值:

function App() {
  const aspectRatio = useImageAspectRatio(imageUrl);

  return (
    <Image 
      src={{ uri: imageUrl }}
      style={{ width: 200, aspectRatio }}
    />
  )
}
Run Code Online (Sandbox Code Playgroud)


Kli*_*akM 5

带有可选style属性和failure回调的 @TheJizel 的TypeScript版本回答Image.getSize

import * as React from 'react'
import {Image} from 'react-native'

interface Props {
    uri: string
    width?: number
    height?: number
    style?
}

interface State {
    source: {}
    width: number
    height: number
}

export default class ScaledImage extends React.Component<Props, State> {
    constructor(props) {
        super(props)
        this.state = {
            source: {uri: this.props.uri},
            width: 0,
            height: 0,
        }
    }

    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})
            }
        }, (error) => {
            console.log("ScaledImage:componentWillMount:Image.getSize failed with error: ", error)
        })
    }

    render() {
        return <Image source={this.state.source} style={[this.props.style, {height: this.state.height, width: this.state.width}]}/>
    }
}
Run Code Online (Sandbox Code Playgroud)

用法示例:

<ScaledImage style={styles.scaledImage} uri={this.props.article.coverImageUrl} width={Dimensions.get('window').width}/>
Run Code Online (Sandbox Code Playgroud)


小智 5

@TheJizel答案的Hooks 版本。我知道宽度但想要图像的高度,所以以下对我有用:

    const ScaledImage = props => {

    const [width, setWidth] = useState()
    const [height, setHeight] = useState()
    const [imageLoading, setImageLoading] = useState(true)

    useEffect(() => {
        Image.getSize(props.uri, (width1, height1) => {
            if (props.width && !props.height) {
                setWidth(props.width)
                setHeight(height1 * (props.width / width1))
            } else if (!props.width && props.height) {
                setWidth(width1 * (props.height / height1))
                setHeight(props.height)
            } else {
                setWidth(width1)
                setHeight(height1)
            }
            setImageLoading(false)
        }, (error) => {
            console.log("ScaledImage,Image.getSize failed with error: ", error)
        })
    }, [])


    return (
        height ?
            <View style={{ height: height, width: width, borderRadius: 5, backgroundColor: "lightgray" }}>
                <Image
                    source={{ uri: props.uri }}
                    style={{ height: height, width: width, borderRadius: 5, }}
                />
            </View>
            : imageLoading ?
                <ActivityIndicator size="large" />
                : null
    );
}
Run Code Online (Sandbox Code Playgroud)

用法 :

<ScaledImage width={Dimensions.get('window').width * 0.8} uri={imageurl} />
Run Code Online (Sandbox Code Playgroud)