image

<img/>태그 이미지 원본 크기+next.js

태그
HtmlNext.jsJavascriptReact
상세설명이미지 원본 크기 구하는 방법
작성일자2023.10.15

Notion Api

image

notion API를 사용하던 중 이미지를 가지고 올 때 크기 값을 보내주지 않는 것을 알고 이미지 크기를 유동적으로 가져오고 싶어서 원본 이미지 크기 값을 가져오는 방법에 대해 알아보았다.

개발자 도구에서 img 태그에 있는 srcset에 있는 이미지 주소에 마우스를 올리면 아래와 같은 이미지가 나온다

image

  • rendered size : 렌더링 되는 이미지 크기
  • intrinsic (본질적인) size : 불러오는 이미지의 원본 크기
  • 여기서 naturalWidth, naturalHeight 활용하면 이미지의 원본 크기를 알아 낼 수 있다.

    기본 html <img/> 태그

    <img id="imageTest" src="A.jpg" width="50" height="100" />

    폭은 100, 높이는 200 인 A.jpg 라는 이미지가 있을 경우 width, height 값이 있으면 해당 크기로 naturalWidth, naturalHeight 를 활용하면 원본 크기로 이미지가 출력 되서 나타난다.

  • 설정한 크기 값 가져오기 (렌더링된 크기)
  • document.getElementById("imageTest").width = 50

    document.getElementById("imageTest").height = 150

  • 이미지의 원본 크기를 알고 싶을 경우
  • document.getElementById("imageTest").naturalWidth = 100

    document.getElementById("imageTest").naturalHeight = 200

    onLoad는 이미지가 로드 된 후 실행하는 함수로 활용 할 수 도 있다.

    <img src="/A.jpg"
    	onLoad = {(e) => {
        	const img = e.target;
            console.log("img 렌더 넓이" , img.width);
            console.log("img 렌더 높이" , img.height);
            console.log("img 원본 넓이" , img.naturalWidth);
            console.log("img 원본 높이" , img.naturalHeight);
        }}
    />

    Next.js <Image/> 태그

    onLoadingComplete : 이미지가 완전히 로딩이 끝나면 호출되는 콜백 함수 관련 속성이다.

    적용 과정

  • onLoadingComplete를 활용하여 naturalWidth, naturalHeight 값을 imageSize의 상태 값에 넣어 Image태그를 감싸고 있는 div의 width, height값으로 할당했다.
  • Image 태그 자체에는 fill 속성을 주어 상위 요소의 크기에 맞춰 채워지게 했다.
  • fill 를 사용하면 이미지 태그에 position: absolute; height: 100%; width: 100%; inset: 0px; color: transparent; 이 스타일들이 적용되기 때문에 상위 태그에 position: "relative" 또는 position: "fixed" position: "absolute" 스타일을 주어야 된다.
  • 그리고 sizes 크기도 지정해줘야 한다.
  • export default function ItemDetailContent() {
    	// image
      const [scrennWidth, setScrennWidth] = useState(   // 화면 크기 
        typeof window !== "undefined" ? window.innerWidth : 0
      );
      const [imageSize, setImageSize] = useState({ width: 1, height: 1 }); // 이미지 크기 
      
      const handleResize = () => {
        setScrennWidth(window.innerWidth);
      };
      useEffect(() => {
        window.addEventListener("resize", handleResize);
        return () => {
          window.removeEventListener("resize", handleResize);
        };
      }, []);
    
      const imageSizeStyles = {
        height: imageSize.height < 30 ? 30 : imageSize.height,
        width:
          imageSize.width > 768 || scrennWidth < 768 ? "100%" : imageSize.width,
      };
    
    	return (
    		<div
    		  key={id}
    		  style={imageSizeStyles}
    		  className="relative my-2 border border-gray-200 dark:border-gray-700"
    		>
    		  <Image
    		     src={image.url}
    		     alt="image"
    		     fill
    		     priority
    		     sizes="100%"
    		     className="object-contain"
    		     onLoadingComplete={({ naturalWidth, naturalHeight }) => {
    		        setImageSize({ width: naturalWidth, height: naturalHeight });
    		     }}
    		   />
    		</div>
    	);
    }

  • 추가로 브라우저 크기에 따라 with, height 값을 변경 하고 싶어서 아래 함수를 활용하여 모바일 화면에서는 width값이 "100%" 로 들어오게 하였다.
  •   const [scrennWidth, setScrennWidth] = useState(   // 화면 크기 
        typeof window !== "undefined" ? window.innerWidth : 0
      );
      const handleResize = () => {
        setScrennWidth(window.innerWidth);
      };
    
      useEffect(() => {
        window.addEventListener("resize", handleResize);
        return () => {
          window.removeEventListener("resize", handleResize);
        };
      }, []);