source

리액트 네이티브에서 이미지 폭을 100%로 설정하고 높이를 자동화하는 방법

factcode 2023. 4. 4. 22:29
반응형

리액트 네이티브에서 이미지 폭을 100%로 설정하고 높이를 자동화하는 방법

스크롤 뷰에 이미지 목록을 표시하려고 합니다.폭은 100%로 하고 높이는 가로 세로 비율을 유지하면서 자동으로 해야 합니다.

검색 결과 전체 화면 배경 스타일을 제공하는 다양한 솔루션이 검색되었습니다.

const styles = StyleSheet.create({
    image: {
        width: null,
        height: 300,
        resizeMode: 'cover'
    }
});

<ScrollView style={{flex: 1}}>
    <Image style={styles.image} source={require('../../../images/collection-imag1.png')}/>
    <Image style={styles.image} source={require('../../../images/collection-imag2.png')}/>
</ScrollView>

폭의 조합은 null, 높이: null, 플렉스: 1, align Self 등 다양합니다.위의 솔루션은 높이가 동적이지 않다는 점을 제외하고는 거의 작동 중입니다.영상의 일부가 보이지 않습니다.

그래서 잠시 생각한 끝에 높이를 얻을 수 있었습니다. 반응 원어민 이미지에서 자동입니다.이 해킹이 작동하려면 이미지 크기를 알아야 합니다.임의의 이미지 뷰어에서 이미지를 열면 이미지 치수가 파일 정보로 표시됩니다.참고로 사용한 이미지의 사이즈는 541 x 362 입니다.

반응 원어민에서 첫 번째 치수 가져오기

import { Dimensions } from 'react-native';

창문의 치수를 구해야 합니다.

const win = Dimensions.get('window');

이제 비율을 다음과 같이 계산합니다.

const ratio = win.width/541; //541 is actual image width

이제 이미지에 스타일을 추가합니다.

imageStyle: {
    width: win.width,
    height: 362 * ratio, //362 is actual height of image
}

"resizeMode"스타일 특성이 아닙니다.컴포넌트의 이미지 컴포넌트로 이동합니다.Props아래 코드처럼.

const win = Dimensions.get('window');

const styles = StyleSheet.create({
    image: {
        flex: 1,
        alignSelf: 'stretch',
        width: win.width,
        height: win.height,
    }
});

...
    <Image 
       style={styles.image}
       resizeMode={'contain'}   /* <= changed  */
       source={require('../../../images/collection-imag2.png')} /> 
...

이미지 컴포넌트의 폭과 높이가 모두 필요하기 때문에 이미지의 높이는 자동으로 설정되지 않습니다.style props따라서 이 답변과 같은 원격 이미지에는 getSize() 메서드를 사용하여 계산할 수 있으며, 이 답변과 같은 정적 이미지의 이미지 비율도 계산할 수 있습니다.

유용한 오픈 소스 라이브러리가 많이 있습니다.

이미지의 aspectRatio(폭/높이)를 알면 폭: "100%", 높이: "auto"솔루션을 찾았습니다.

코드는 다음과 같습니다.

import { Image, StyleSheet, View } from 'react-native';

const image = () => (
    <View style={styles.imgContainer}>
        <Image style={styles.image} source={require('assets/images/image.png')} />
    </View>
);

const style = StyleSheet.create({
    imgContainer: {
        flexDirection: 'row'
    },
    image: {
        resizeMode: 'contain',
        flex: 1,
        aspectRatio: 1 // Your aspect ratio
    }
});

것이 입니다.onLayout ★★★★★★★★★★★★★★★★★」Dimension□□. 따라 .필요한 경우 재사용 가능한 간단한 구성 요소로 포장할 수도 있습니다.심플한 실장을 원하는 사람이 있다면 시도해 보세요.

aspectRatio 속성을 스타일로 사용

애스펙트비는 노드의 정의되지 않은 치수의 크기를 제어합니다.애스펙트비는 CSS가 아닌 리액트 네이티브에서만 사용할 수 있는 비표준 속성입니다.

  • 가로/높이 석면비가 설정된 노드에서 설정되지 않은 치수의 크기를 제어합니다.
  • 플렉스 베이스 애스펙트비가 설정된 노드에서는 설정되지 않은 경우 크로스 축의 노드 크기를 제어합니다.
  • 측정 함수의 애스펙트비가 있는 노드에서 측정 함수는 플렉스 기준을 측정하는 것처럼 작동합니다.
  • 확장/축소 애스펙트비가 유연한 노드에서는 설정되지 않은 경우 크로스 축의 노드 크기를 제어합니다.
  • 애스펙트비는 최소/최대 치수를 고려

문서: https://native.dev/syslog/syslog-syslogs#syslogratio

다음과 같이 시도합니다.

import {Image, Dimensions} from 'react-native';

var width = Dimensions.get('window').width; 

<Image
    source={{
        uri: '<IMAGE_URI>'
    }}
    style={{
        width: width * .2,  //its same to '20%' of device width
        aspectRatio: 1, // <-- this
        resizeMode: 'contain', //optional
    }}
/>

나는 위의 모든 해결책에 문제가 있었다.마지막으로 나는 aspectRatio를 이용해 속임수를 썼다.이미지 폭과 높이를 알고 있고 크기가 큰 경우 aspect Ratio를 계산하여 다음과 같이 이미지에 추가합니다.

<PhotoImage
    source={{uri: `data:image/jpeg;base64,${image.base64}`}}
    style={{ aspectRatio: image.width / image.height }}
 />

Aspect Ratio는 React Native의 레이아웃 속성으로 이미지의 애스펙트 비율을 유지하고 상위 컨테이너에 들어갑니다.https://facebook.github.io/react-native/docs/layout-props#aspectratio

.Image사이징은 자동으로 이루어지지 않습니다.리액트 네이티브 의사가 그러더군요

총 .ScrollView를 사용합니다.onLayout.Image를 기반으로 합니다.「 」를 사용하고 resizeModecover.Image하지만 컨테이너보다 크면 잘라낼 수 있습니다.

이미지를 오른쪽 클릭하여 해상도를 확인합니다.내 경우 1233 x 882

const { width } = Dimensions.get('window');

const ratio = 882 / 1233;

    const style = {
      width,
      height: width * ratio
    }

<Image source={image} style={style} resizeMode="contain" />

그것뿐입니다

솔루션 2020년 4월:

위의 답변은 귀엽지만 모두 큰 결점이 있습니다.사용자의 디바이스 폭에 따라 화상의 높이를 계산하고 있다는 것입니다.

진정으로 반응하는 것(즉,width: 100%, height: auto)의 실장에서는, 정말로 실시하고 싶은 것은, 부모 컨테이너의 폭에 근거해 이미지의 높이를 계산하는 것입니다.

다행히 React Native는 OnLayout View 메서드 덕분에 상위 컨테이너 너비를 얻을 수 있는 방법을 제공합니다.

'를 '보기'로 됩니다.width: "100%" , 을 사용합니다.onLayout해당 보기의 너비(즉, 용기 너비)를 얻은 다음 해당 용기 너비를 사용하여 이미지의 높이를 적절하게 계산합니다.

 

암호만 보여줘...

RN의 Image.get Size를 사용하여 Responseive Image 컴포넌트 내의 이미지 치수를 취득함으로써 다음 솔루션을 더욱 개선할 수 있습니다.

JavaScript:

// ResponsiveImage.ts

import React, { useMemo, useState } from "react";
import { Image, StyleSheet, View } from "react-native";

const ResponsiveImage = props => {
  const [containerWidth, setContainerWidth] = useState(0);
  const _onViewLayoutChange = event => {
    const { width } = event.nativeEvent.layout;
    setContainerWidth(width);
  }

  const imageStyles = useMemo(() => {
    const ratio = containerWidth / props.srcWidth;
    return {
      width: containerWidth,
      height: props.srcHeight * ratio
    };
  }, [containerWidth]);

  return (
    <View style={styles.container} onLayout={_onViewLayoutChange}>
      <Image source={props.src} style={imageStyles} />
    </View>
  );
};

const styles = StyleSheet.create({
  container: { width: "100%" }
});

export default ResponsiveImage;


// Example usage...

import ResponsiveImage from "../components/ResponsiveImage";

...

<ResponsiveImage
  src={require("./images/your-image.jpg")}
  srcWidth={910} // replace with your image width
  srcHeight={628} // replace with your image height
/>

 

Type Script:

// ResponsiveImage.ts

import React, { useMemo, useState } from "react";
import {
  Image,
  ImageSourcePropType,
  LayoutChangeEvent,
  StyleSheet,
  View
} from "react-native";

interface ResponsiveImageProps {
  src: ImageSourcePropType;
  srcWidth: number;
  srcHeight: number;
}

const ResponsiveImage: React.FC<ResponsiveImageProps> = props => {
  const [containerWidth, setContainerWidth] = useState<number>(0);
  const _onViewLayoutChange = (event: LayoutChangeEvent) => {
    const { width } = event.nativeEvent.layout;
    setContainerWidth(width);
  }

  const imageStyles = useMemo(() => {
    const ratio = containerWidth / props.srcWidth;
    return {
      width: containerWidth,
      height: props.srcHeight * ratio
    };
  }, [containerWidth]);

  return (
    <View style={styles.container} onLayout={_onViewLayoutChange}>
      <Image source={props.src} style={imageStyles} />
    </View>
  );
};

const styles = StyleSheet.create({
  container: { width: "100%" }
});

export default ResponsiveImage;


// Example usage...

import ResponsiveImage from "../components/ResponsiveImage";

...

<ResponsiveImage
  src={require("./images/your-image.jpg")}
  srcWidth={910} // replace with your image width
  srcHeight={628} // replace with your image height
/>

이미지 태그는 다음과 같은 스타일을 사용할 수 있습니다.

imageStyle: {
    width: Dimensions.get('window').width - 23,
    resizeMode: "contain",
    height: 211,
 },

이것은 이미지 폭 100%의 이미지 높이를 자동 조정하는 데 도움이 될 수 있습니다.

이미지: { width: "100%", 크기 조정모드: "중앙" "포함", 높이: 정의되지 않음, 석면비: 1, }

이미지 치수를 취득해 폭이나 높이를 올바르게 설정할 수 있는 것을 공유합니다.또한 이 코드를 통해 필요한 큰 이미지 데이터가 전송되는 동안 로드된 이미지를 가져올 수 있습니다.

  1. 정적 메서드 Image.prefetch를 사용하여 이미지를 다운로드하여 캐시할 수 있도록 합니다.

  2. 정적 메서드 Image.getSize를 사용하여 높이와 폭을 수집하고 이를 사용하여 석면비를 계산한 후 최종 높이(또는 폭)를 계산합니다.

  3. 원하는 너비에 대한 기본 스타일로 이미지를 표시합니다(높이는 아스펙트 비율을 유지한 상태로 계산됩니다).

     function ImageX(props: {source: string, id: string})
     {
       const [imageHeight, setImageHeight] = React.useState(1);
       Image.prefetch(props.source)
       .then(() => {
           Image.getSize(props.source, (width, height) => {
             let aspectRatio =  height/width;
             setImageHeight(aspectRatio*Dimensions.get('window').width);
           });
       })
       .catch(error => console.log(error))
       if (imageHeight <=1) //Image not in cache (disk) yet
         {
           return (
             <Image key={props.id} style={styleimg.image} source={{uri: 'http://www.dsdsd/loaderpreview.gif'}}/>
           );
       }
       else
       {
         return (
           <Image key={props.id} style={styleimg.image} height={imageHeight} source={{uri: props.source}}/>
         );
       }
     }
    

    const styleimg = StyleSheet.create({ 이미지: {width: Dimensions.get('창'))).폭, 크기 조정모드: 'contain' //... // 높이 기본값을 설정할 수 있습니다. }} ;

저는 존 제임스의 아이디어를 이미지 컨테이너 대신 이미지 자체에 적용했습니다.이것이 제가 사용한 것입니다.그것은 훌륭하게 동작합니다.

import { useState, useEffect } from 'react';
import { Image } from 'react-native';

export default function AutoHeightImage({ uri, style }) {
  const [paintedWidth, setPaintedWidth] = useState(0);
  const [resultHeight, setResultHeight] = useState(0);

  useEffect(() => {
    let stillMounted = true;
    Image.getSize(uri, (realW, realH) => {
      if (!paintedWidth || !stillMounted) return;
      const shrinkRatio = realW / paintedWidth;
      setResultHeight(realH / shrinkRatio);
    });
    return () => (stillMounted = false);
  }, [paintedWidth]);

  return (
    <Image
      style={[{ width: '100%' }, style, { height: resultHeight }]}
      source={{ uri }}
      onLayout={(event) => setPaintedWidth(event.nativeEvent.layout.width)}
    />
  );
}

사용해보십시오.Image.getSize(uri, (width, height) => {console.log(width, height);});.

const Image = url => {
  const [aspectRatio, setAspectRatio] = useState(1.2);
  Image.getSize(
    url,
    (width, height) => {
      setAspectRatio(width / height);
    },
  );
  return (
    <Image
      source={{
        uri: url
      }}
      style={{width: '100%', aspectRatio: aspectRatio}}
      resizeMode="cover"
    />
  );
};

function ImageX( props){
   const [state, setState] = React.useState({v:{height:1}});
   useEffect(() => {
    if(!props.source || !props.source.uri) return;
    Image.prefetch(props.source.uri)
    .then(() => {
        Image.getSize(props.source.uri, (width, height) => {
          let aspectRatio =  height/width;
          state.v.width=Dimensions.get('window').width;
          state.v.height=aspectRatio*state.v.width;
          setState({...state});
        });
    })
    .catch(error => console.log(error))
   },[props.source && props.source.uri]);
   
   if (state.v.height <=1) //Image not in cache (disk) yet
     {
      return (
        <Image {...props}/>
      );
   }
   else
   {
     let neededst={v:{width:state.v.width, height:state.v.height}}
     let st={v:props.style};
    assignObject(neededst, st);
     return (
       <Image {...props} style={neededst.v}/>
     );
   }
 }

 function assignObject(target, source) {
  if (!source) return;
  for (let k in target) {
    let v = target[k];
    if (Object(v) === Object) assignObject(v, source[k]);
    else {
      if (source[k]) {
        try {
          Object.assign(v, source[k]);
        } catch (e) {
          alert(e);
        }
      }
    }
  }

  for (let k in source) {
    if (!target[k]) {
      target[k] = source[k];
    }
  }

}

https://reactnativeelements.com/docs/image의 이미지 컴포넌트 사용

언급URL : https://stackoverflow.com/questions/39631895/how-to-set-image-width-to-be-100-and-height-to-be-auto-in-react-native

반응형