이미지 프로세스 이해 (이미지 서버, 스토리지 포함)

huni_·2022년 7월 6일
1

React

목록 보기
29/57

이미지 프로세스를 이해하기 위해서는 storage 사용을 알아야 합니다.

storage 또한 컴퓨터이며 여러 컴퓨터들을 연결시켜 놓은 큰 용량을 담을 수 있는 데이터베이스 입니다.

uploadFile 이라는 api가 있을때, 파일을 선택하고 uploadFile을 요청하게 될 경우, backend에서 storage로 파일을 전송하게 됩니다.

우리가 이미지를 보기 위해서는 주소를 사용해 접근하게 됩니다.

즉, storage에서는 backend로 이미지 주소를 넘겨주게 되며 이 주소를 다시 front에게 주게 됩니다. 우리는 이 주소를 가지고 api 요청 시, image에 대한 주소를 보낼 수 있게 되는 것 이며, 이 정보들을 DataBase에 저장하게 됩니다.

(imgFile에 접근 할 수 있는 주소만 저장 file 없음).

💡 storage는 어디에 있나요?

AWS, GCP, AZURE와 같은 클라우드 안에 있습니다.


이미지 업로드를 위한 URL 받아오기

우리가 이미지 업로드에 사용할 api는 uploadFile 입니다.

이미지 업로드는 uploadFile로 받아온 이미지 url을 createBoard에 넣어주시면 됩니다.

url을 받아오기 위해선 아폴로 업로드 관련 라이브러리를 설치해줘야 합니다. 아래 순서를 따라 설치와 세팅을 해주시길 바랍니다.

아폴로 업로드 라이브러리 설치와 세팅

url을 가지고 오기위한 라이브러리로 createUploadLink를 설치해야 합니다.

라이브러리 설치 apollo-upload-client_github

터미널에 yarn add apollo-upload-client 입력해!
설치해주세요

사용을 위한 세팅

  1. app.tsx에서 세팅해주기
// class 폴더의 app.tsx파일
// import 부분
import {ApolloLink} from "@apollo/client"
import {createUploadLink} from "apollo-upload-client"

//세팅 함수 부분
const uplodLink = createUploadLink({
	uri : "백엔드 주소"
})
const client = new ApolloClient({
	link : ApolloLink.from([uplodLink as unknown as ApolloLink]),
	cache : new inMemoryCache(),
})

💡 아폴로 업로드의 타입스크립트

아폴로 업로드는 타입스크립트 또한 지원해주는 라이브러리 입니다. 따라서 타입을 설치해주도록 하겠습니다.
설치
yarn add @types/apollo-upload-client --dev 를 입력해 설치 해줍니다.

이렇게 설치와 세팅을 완료하면 사용을 위한 준비는 모두 완료되었습니다.

그럼 본격적으로 이미지 URL을 받아와볼까요?

파일 업로드할 수 있도록 화면 그려주기

파일을 선택할 수 있도록 input 태그typefile로 지정해 그려주겠습니다.

//index.tsx 파일

const UPLOAD_FILE = gql`
	mutation uploadFile($file:Upload!){
		uploadFile(file:$file){
			url
	}
}
`

const ImageUPloadPage = (e)=>{
	const onchangeFile = async(e:ChangeEvent<HTMLInputElement>)=>{
		const [uploadFile] = useMutation(UPLOAD_FILE)

		//files는 있을수도 있고,없을수도 있기 때문에 옵셔널 체이닝을 사용해주셔야 합니다.
		const Imagefile = e.target.files?.[0]
		try{
			await uploadFile({ variables : {file : Imagefil} })
			console.log(result.data?.uploadFile.url)
		} catch(error){
			alert(error.message)
		}
	}

	return <input type="file" onChange={onChangeFile}/>
}

클라우드에 이미지를 보내주고, url을 받아오는 과정 을 자세히 보도록 하겠습니다.

  1. onchange를 통해 이미지 파일을 가지고와 Imagefile에 넣어줍니다.
  2. Imagefilevariables에 넣어 uploadFile mutation을 날려줍니다.
  3. 이미지가 정해둔 스토리지에 들어가고, 해당 스토리지에서 url을 반환 받아 가지고 옵니다.
  4. 콘솔에 받아온 이미지 URL이 찍힙니다.

💡 ‼️ 해당 url의 이미지를 보고싶다면, 저장해둔 스토리지 주소의 뒤에 이미지 url을 적어주시면 됩니다.

[예시](http://storage.goolgeapis.com/이미지url](http://storage.goolgeapis.com/이미지url)


이미지 확장자 검증하기

이미지 파일을 input 태그에 넣을 때 확장자를 검증하는 방법은 크게 2가지가 있습니다.

첫 번째 방법은 input 태그에 accept 속성을 이용하는 것이고,

두 번째 방법은 onChange 함수 안에서 type을 비교하는 것입니다.

하나씩 보도록 하겠습니다.

input 태그에 accept 속성 활용하여 확장자 검증하기

input 태그에는 accept 속성이 있습니다.

아직 accept 속성을 넣기 전 입니다.

이 상태에서 파일 선택을 눌러보겠습니다.

<div>
	<img style={{ width: '500px' }} id="image" />
	<input type="file" onChange={readImage}></input>
</div>

보면 모든 파일이 선택 가능합니다.

이번에는 accept 속성을 이용해 png파일만 올릴 수 있도록 코드를 바꿔보겠습니다.

<div>
	<img style={{ width: '500px' }} id="image" />
	<input type="file" **accept="image/png"** onChange={readImage}></input>
</div>

굵게 표시된 부분이 추가된 코드입니다.

accept 속성에 우리가 원하는 확장자를 넣게 되면 다른 확장자는 클릭이 안 되도록 막히게 됩니다.

아래 사진을 보면 png 확장자만 클릭 활성화가 되어있습니다.


onChange 함수 안에서 type을 이용하여 검증하기

input 태그에 파일을 넣으면 해당 파일의 정보를 target.files[0]으로 알 수 있습니다.

console.log()로 어떤 정보가 있는지 확인해 보았습니다.

export default function Web() {
	const readImage = (input) => {
		// 인풋 태그에 파일이 있는 경우
		if (input.target.files && input.target.files[0]) {
			console.log(input.target.files[0]);
			// FileReader 인스턴스 생성
			const reader = new FileReader();
			// reader가 이미지 읽도록 하기
			reader.readAsDataURL(input.target.files[0]);
			// 이미지가 로드가 된 경우
			reader.onload = (e) => {
				const previewImage = document.getElementById('image');
				previewImage.src = e.target.result;
			};
		}
	};

	return (
		<>
			<div>
				<img style={{ width: '500px' }} id="image" />
				<input type="file" onChange={readImage}></input>
			</div>
		</>
	);
}

이미지를 각각 2번 넣어보았습니다.

보면 type에 우리가 올린 파일의 확장자가 무엇인지 알 수 있습니다.

그럼 if()사용해서 "image/png"일 경우에만 미리보기를 만들어 주면 됩니다.

아래 코드를 보면 if를 사용해서 확장자가 png일 경우에만 미리보기를 하도록 하였습니다.

export default function Web() {
	const readImage = (input) => {
		// 인풋 태그에 파일이 있는 경우
		if (input.target.files && input.target.files[0]) {
			//png일 경우에만 코드 실행
			if (input.target.files[0].type !== 'image/png') {
				alert('png만 가능합니다.');
			} else {
				// FileReader 인스턴스 생성
				const reader = new FileReader();
				// reader가 이미지 읽도록 하기
				reader.readAsDataURL(input.target.files[0]);
				// 이미지가 로드가 된 경우
				reader.onload = (e) => {
					const previewImage = document.getElementById('image');
					previewImage.src = e.target.result;
				};
			}
		}
	};

	return (
		<>
			<div>
				<img style={{ width: '500px' }} id="image" />
				<input type="file" onChange={readImage}></input>
			</div>
		</>
	);
}

이미지 용량 검증하기

우리는 이미지 용량도 제한할 수 있습니다. 너무 큰 파일을 올리면 부담이 가니까요.

위에서 target.files[0]을 이용해 파일 정보를 확인했었습니다. 다시 볼까요?

보시면 size도 알 수 있습니다. 하지만 "123494"가 어떤 파일 크기를 얘기하는지는 한 번에 알기 힘듭니다.

위에 나온 사이즈를 알기 쉽게 비교하는 방법은 1 * 1024 * 1024 를 이용하는 것입니다.

1 1024 1024 는 1MB입니다.

5 1024 1024 는 5MB죠.

위의 식을 이용해서 if문을 활용하면 파일 사이즈를 제한할 수 있습니다.


const readImage = (input) => {
	// 인풋 태그에 파일이 있는 경우
	if (input.target.files && input.target.files[0]) {
		const fileSize = 5 * 1024 * 1024;
		if (input.target.files[0].size > fileSize) {
			alert('5MB이하만 가능합니다 .');**
		} else {
		// FileReader 인스턴스 생성
		const reader = new FileReader();
		// reader가 이미지 읽도록 하기
		reader.readAsDataURL(input.target.files[0]);
		// 이미지가 로드가 된 경우
		reader.onload = (e) => {
			const previewImage = document.getElementById('image');
			previewImage.src = e.target.result;
		}};
	}
};

위 코드에서 붉게 표시된 부분이 파일 용량을 제한하는 방법입니다.


HTML 기본 FILE 태그 숨기기

아무리 봐도 기본 input태그는 너무 못 생겼습니다.

그래서 input태그를 숨기고, 다른 녀석으로 교체해주는 방법을 알아보겠습니다.

크게 2가지 방식이 있습니다.

Label 태그와 htmlFor 사용하기

Label 태그에는 htmlFor이라는 속성이 있습니다. 이 속성에 값을 넣으면 값과 똑같은 id를 찾아 그 태그의 기능과 연결해줍니다.

<div>
	<label htmlFor="fileTag">이거 눌러도 실행돼요!</label>
	<img style={{ width: '500px' }} id="image" />
	<input id="fileTag" type="file" onChange={readImage}></input>
</div>

노란색 부분이 label 태그 입니다. htmlFor="fileTag"input의 id="fileTag" 의 값이 똑같습니다.

그럼 어떤 결과가 있는지 한 번 보겠습니다.

위의 결과를 보면 label 태그를 클릭해도 똑같이 파일을 올릴 수 있습니다.

그러면 label태그를 우리가 원하는 디자인으로 꾸미고, 기존 input 태그는 안 보이도록 CSS를 작업하면 됩니다.


useRef 이용하기

우리가 HTML 태그를 선택할 때는 보통 getElementId를 사용했습니다.

react에서는 HTML 태그에 접근을 도와주는 역할을 useRef가 하고 있습니다.

우선 간단하게 사용 방법을 보도록 하겠습니다. 위의 예제에서 htmlFor부분을 없애고 useRef로 똑같이 한 번 만들어 보겠습니다.

import { useRef } from 'react';

export default function Web() {
	const inputEl = useRef();

}

우선 바뀐 부분을 먼저 보기 위해 이미지 미리보기 코드는 잠시 지웠습니다.

보시면 제일 위에서 import로 useRef를 가져오고 const inputEl = useReft(); 를 작성했습니다.

이게 가장 처음 Ref를 불러오고 사용하는 기본 설정입니다. useState나 useEffect처럼 react에서 가져와야 사용할 수 있습니다.

이렇게 하고 inputEl을 태그에 넣어주면 그 태그는 inputEl로 대신 사용할 수 있습니다.

태그에 넣어주는 것도 한 번 코드로 보곘습니다.

<input
	ref={inputEl}
	id="fileTag"
	type="file"
	onChange={readImage}
></input> 

이렇게 input 태그에 ref={inputEl}을 작성하면 이제 input 태그를 inputEl을 이용해 사용할 수 있습니다.

그리고 나서, useRef에 있는 기능을 이용해주면 됩니다.

useRef에는 다양한 기능이 있지만, 지금은 하나만 보도록하겠습니다.

const handleFileBtn = () => {
	inputEl.current.click();
};

함수를 하나 만들어주었습니다.

onClick에 넣을 함수인데, Ref에는 current 안에 click이라는 기능이 있습니다.

이름 그대로 current는 inputEl에 들어온 태그를 뜻하고, 그 태그를 click하겠다는 기능입니다.

<button onClick={handleFileBtn}>이미지 등록 버튼</button>

그리고 새로운 버튼을 하나 만들어서 해당 기능을 넣어주었습니다.

이렇게 하면 button을 클릭했을 때 inputEl.current.click();이 실행될 것이고, 그것은 우리가 useRef에 넣어두었던 input 태그를 클릭한 것과 같은 결과가 나올 것입니다.

보시면 이미지등록버튼 을 눌렀을 때 input태그를 클릭한 것과 같은 결과가 발생합니다.

여기까지 하면 useRef로 input 태그의 기능을 대신 하는 것은 끝났습니다.

그러면 조금 더 응용을 해볼까요?

return (
	<>
		<div>
			<img **onClick={handleFileBtn}** style={{ width: '500px' }} id="image" />
			<input
				hidden={true}
				ref={inputEl}
				id="fileTag"
				type="file"
				onChange={readImage}
			></input>
			<button onClick={handleFileBtn}>이미지 등록 버튼</button>
		</div>
	</>
);

위의 코드를 보시면 미리보기 이미지에도 handleFileBtn을 넣어주었습니다. handleFileBtn이 어떤 기능인지는 위에서 설명을 했습니다.

그리고 input 태그에는 hidden 기능을 이용해 태그를 숨겨주었습니다.

이러면 우리는 미리보기 이미지를 클릭할 때, 이미지 등록 버튼을 클릭할 때 모두 input type=file 태그를 클릭한 것과 동일한 결과를 볼 수 있습니다.

import { useRef } from 'react';

export default function Web() {
	const inputEl = useRef();

	const readImage = (input) => {
		// 인풋 태그에 파일이 있는 경우
		if (input.target.files && input.target.files[0]) {
			// FileReader 인스턴스 생성
			const reader = new FileReader();
			// reader가 이미지 읽도록 하기
			reader.readAsDataURL(input.target.files[0]);
			// 이미지가 로드가 된 경우
			reader.onload = (e) => {
				const previewImage = document.getElementById('image');
				previewImage.src = e.target.result;
			}
		}
	};

	const handleFileBtn = () => {
		inputEl.current.click();
	};

	return (
		<>
			<div>
				<img onClick={handleFileBtn} style={{ width: '500px' }} id="image" />
				<input
					hidden={true}
					ref={inputEl}
					id="fileTag"
					type="file"
					onChange={readImage}
				></input>
				<button onClick={handleFileBtn}>이미지 등록 버튼</button>
			</div>
		</>
	);
}

전체 코드입니다.


이미지 미리보기 (임시 주소 생성)

자바스크립트에서 이미지를 보기 위해서는 이미지 경로(주소)가 필요합니다.

Pre Camp 때 싸이월드를 만들면서 이미지 주소를 다들 해보셨을 겁니다.

../../ 이런 식으로 사용했었죠.

하지만 위와 같은 경로에는 단점이 하나 있습니다. 다른 사람 컴퓨터에 해당 이미지가 없을 경우에는 오류가 뜨는 것이죠.

그래서 위에 애기했 듯이 이미지 서버에 이미지를 등록하고 등록된 이미지 주소로 불러와야 어디서든 이미지를 볼 수 있었습니다.

하지만, 이미지를 올려놓고 정작 게시글 등록을 하지 않으면, 이미지 서버에는 이미지가 올라가 있지만, 사용되는 곳은 없죠. 그래서 쓸데없는 데이터 낭비뿐만 아니라, 서버에도 과부하가 걸리게 됩니다.

그래서 이미지 주소를 서버에서 가져오는 것이 아니라, 미리보기 용으로 만든 임시 주소를 만드는 방법이 있습니다.

이번에도 간단한 예제가 있습니다.

export default function Web() {
	return (
		<>
			<div>
				<img style={{ width: '500px' }} id="image" />
				<input type="file"></input>
			</div>
		</>
	);
}

아직은 크게 어려울 것이 없는 코드입니다.

브라우저에서는 딱 [파일 선택] "선택된 파일 없음" 만 있습니다.

<input type="file"></input> 를 처음 보시는 분도 있을 겁니다. input typefile로 지정하면 파일을 올릴 수 있습니다.

하지만 단순히 파일만 올리게 되면 파일 정보에 대한 값을 확인 할 수 없습니다. 그래서 함수를 하나 만들어 주도록 하겠습니다.

input.target.files

export default function Web() {

	const readImage=(input)=> {
		console.log(input.target.files);
	}

	return (
		<>
			<div>
				<img style={{ width: '500px' }} id="image" />
				<input type="file" onChange={readImage}></input>
			</div>
		</>
	);
}

굵게 표시된 부분이 새로 추가된 부분입니다.

기존 코드에서 readImage라는 함수를 하나 만들어 주고, input에 onChange로 함수를 실행시켜주었습니다.

그리고 그 결과를 console.log(input.target.files)로 어떤 파일이 들어오는지 확인을 했습니다.

input.target.files는 우리가 파일을 올렸을 때 데이터가 들어가는 곳입니다.

파일을 하나 올려보겠습니다.

콘솔창에 이런 결과가 나왔습니다.

해당 결과를 가지고 이미지 미리보기를 만들 수 있습니다.

new FileReader()

new FileReader() 기능은 파일 객체를 이용해 내용을 읽고 사용자 컴퓨터에 저장하는 것을 가능하게 해주는 기능입니다.

new FileReader() 를 사용하면 new FileReader() 에 있는 기능들을 이용할 수 있습니다.

우선 전체적인 코드는 아래와 같습니다.

export default function Web() {
	const readImage = (input) => {
		// 인풋 태그에 파일이 있는 경우
		if (input.target.files && input.target.files[0]) {

			// FileReader 인스턴스 생성
			const reader = new FileReader();

			// reader가 이미지 읽도록 하기
			reader.readAsDataURL(input.target.files[0]);

			// 이미지가 성공적으로 읽힌 경우 onload가 실행됩니다. 
			reader.onload = (e) => {
				const previewImage = document.getElementById('image');
			// 생성된 Data URL이 e.target.result에 담기게 됩니다. 
			// 그 결과를 src에 넣어주게 되면 끝입니다. 
				previewImage.src = e.target.result;
			};
		}
	};

	return (
		<>
			<div>
				<img style={{ width: '500px' }} id="image" />
				<input type="file" onChange={readImage}></input>
			</div>
		</>
	);
}

new FileReader() 기능을 const reader에 담아주었습니다. 그러면 readernew FileReader()의 기능을 사용할 수 있습니다.

readAsDataURL()

readAsDataURL()을 사용하면 Data URL을 얻을 수 있게 됩니다.

()안에 우리가 넣은 파일을 넣어주면 됩니다.

onload()

파일 읽기에 성공하게 되면 onload가 실행됩니다.

onload에서는 파일을 읽고 생성된 Data URLtarget.result에 담기게 됩니다.

해당 결과를 img태그src에 값으로 넣어주게 되면 됩니다.

여기까지하면 전체적인 흐름은 끝입니다.

위 기능을 이용해서 만들어진 data URL 입니다.

기능도 잘 작동합니다.

추가

new FileReader() 을 이용하여 로직을 조금 더 추가하면 파일 확장자를 png로 제한할 수도 있고, 파일 크기도 제한할 수 있습니다.

해당 로직은 아래에서 더 해보도록 하겠습니다.


다중 이미지 업로드 (for vs Promise.all) - map vs forEach vs for

위에서 배운 내용은 이미지를 1번에 1개 씩만 올렸을 때 입니다. 이번에는 이미지를 여러 개를 한 번에 등록하는 방법을 알아보도록 하겠습니다.

우선, 위에서 작업했던 코드를 그대로 가져오도록 하겠습니다. 미리보기도 모두 그대로 입니다.

<input> 태그에 multiple이라는 속성을 이용하면 동시에 여러 개의 이미지를 등록할 수 있습니다.


return (
	<>
		<div>
			<img onClick={handleFileBtn} style={{ width: '500px' }} id="image" />
			<input
				hidden={true}
				ref={inputEl}
				id="fileTag"
				type="file"
				multiple
				onChange={readImage}
			></input>
			<button onClick={handleFileBtn}>이미지 등록 버튼</button>
		</div>
	</>
);

그리고 나서 한 번 console.log()로 어떻게 오는지 한 번 보겠습니다.

FileList는 배열 안의 객체 형태로 데이터가 들어옵니다.

다중 이미지 미리보기

그러면 가장 간단한 for을 이용해서 한 번에 파일을 여러 개 미리보기 해보겠습니다.

import { useRef, useState } from 'react';

export default function Web() {
	const inputEl = useRef();

	const [imgArr, setImgArr] = useState([]);

	const readImage = (input) => {
		// 미리보기 URL을 담아줄 임시 배열
		let newArr = [];
		// 인풋 태그에 파일이 있는 경우
		if (input.target.files) {
	
			//들어간 파일의 길이만큼 반복
			for (let i = 0; i < input.target.files.length; i++) {
				// FileReader 인스턴스 생성
				const reader = new FileReader();
				// reader가 이미지 읽도록 하기
				reader.onload = (e) => {
					// 미리보기 URL을 스테이트에 저장
					newArr[i] = e.target.result;
					setImgArr([...newArr]);
				};
				reader.readAsDataURL(input.target.files[i]);
			}
		}
	};

	const handleFileBtn = () => {
		inputEl.current.click();
	};

	return (
		<>
			<div>
				{imgArr.length ? (
					imgArr.map((data) => (
						<img
							src={data}
							onClick={handleFileBtn}
							style={{ width: '500px' }}
							id="image"
							ref={inputEl}
						/>
					))
				) : (
					<div>이미지 없음</div>
				)}

				<input
					hidden={true}
					ref={inputEl}
					id="fileTag"
					type="file"
					multiple
					onChange={readImage}
				></input>
				<button onClick={handleFileBtn}>이미지 등록 버튼</button>
			</div>
		</>
	);
}

대부분의 코드가 위에서 함께 배웠던 코드라 길게 설명은 하지 않겠습니다.

아마 여기까지 오신 분들은 map을 이용해 데이터를 한 꺼번에 뿌리는 것도 익숙하실 거라 믿습니다.

다중 이미지 업로드

위에서 이미지 업로드를 위해서 동기 방식으로 이미지 서버에 등록을 먼저 하고,

이미지 서버에서 준 URL을 사용했어야 했습니다.

그러면 이미지가 3개라면 이미지 서버를 3번 왔다 갔다 해야 합니다. 그럴 때 어떤 방법이 가장 빠를까요?

다중 이미지 업로드 - for

먼저 반복문으로 이미지 업로드를 3번 해보겠습니다.

for (let i = 0; i < 3; i++) {
	input.images.map((file) => uploadFileMutation({ variables: { file } }));
}

그랬을 때 결과입니다. 시간 초를봐주세요.

평균 3s가 걸립니다. 반복문으로 할 경우 3번의 보냄, 3번의 기다림, 3번의 성공이 있습니다.

다중 이미지 업로드 - Promise.all

Promise.all은 동기 요청을 한 번에 보내는 역할을 해줍니다.

반복문 보다 시간초가 덜 걸리는 것을 볼 수 있습니다.

Promise.all()은 아래와 같이 인자로 배열형태가 들어가게 됩니다.

Promise.all() 예제는 따로 없습니다. 한 번 직접 적용해보세요!

Promise.all([p1, p2, p3])

이미지 Webp 확장자

webp 확장자는 구글에서 만든 이미지 포맷입니다.(웹피라고 부릅니다.) png, jpeg와 같은 이미지 확장자입니다

구글에서는 왜 webp 확장자를 만들었을 까요?

구글은 전세계적으로 사용하고 있는 사이트 입니다. 구글에서만 관리하고 있는 이미지 서버만 해도 엄청난 트래픽이 있습니다.

구글은 이미지 서버의 부담을 줄이고, 서버비를 아낄 수 있는 방안으로 Webp라는 확장자를 만들었습니다.

Webp의 장점

WebpGIF, PNG, JPEG 확장자 모두를 대체 가능한 확장자이며 이미지를 파일을 압축했을 때 기존 PNG, JPEG보다 약 30%정도 용량을 줄일 수 있는 장점이 있습니다.

같은 이미지를 webp으로 받을시 webp은 300kb라면 png는 500kb정도 됩니다.

그리고 GIF는 256색만 표현할 수 있지만, Webp은 파일 크기도 작고 , 색상 수에 제한이 없으므로 GIF보다 훨씬 좋은 성능을 보입니다.

또한 PNG 처럼 알파 채널을 지원합니다.

알파 채널이란 배경이 투명한 것을 이야기 합니다.

Webp 확장자 변환하기

우리의 이미지 파일을 Webp 확장자로 변환시켜주는 아주 착한 사이트가 있습니다.

Webp 확장자 변환 사이트 << 링크를 클릭하면 이동 합니다.

1. Select File를 누른다

2. 선택한 파일을 어떤 파일로 변환시킬지 고른다. (Webp를 선택하겠습니다.)

3. Convert를 누르면 완료.


이미지 라이브러리 (React-dropzone, react-avator-editor, ant-design)

이미지 등록을 예쁘게 만들어주는 기능들이 이미 많이 있습니다. 그래서 직접 디자인 하지 않아도 됩니다.

이번 내용은 소개만 해드립니다. 직접 적용 및 구현 코드는 따로 알려드리지 않습니다.

React-dropzone

npm 주소 < 클릭하시면 React-dropzone Npm으로 이동할 수 있습니다.

React-dropzone은 react에서 제공하는 대표적인 이미지 라이브러리입니다.

react-avator-editor

npm 주소 < 클릭하시면 react-avator-editor Npm으로 이동할 수 있습니다.

React-dropzone에 비하면 다운로드 수가 많이 적지만, 좋은 기능들을 담고 있는 라이브러리입니다.

이름이 avator라서 영화 아바타의 이미지를 예제로 사용하고 있습니다.

ant-design

ant-design-img <클릭시 ant-design 으로 이동할 수 있습니다.

ant-design에서도 제공해주는 이미지 기능이 많습니다.

직접 구현할 수도 있고, 여러 라이브러리를 사용하여 구현할 수 있습니다.

무조건 직접 구현하는 것이 좋은 것도 아니고, 무조건 라이브러리만 사용해서 구현하는 것도 좋은 것이 아닙니다.

가장 좋은 것은 직접 구현할 수도 있고, 라이브러리를 사용하는 방법을 모두 익혀 어떤 상황에서도 기능을 구현하는 것입니다.

직접 구현도 해보시고, 라이브러리도 사용해 보세요!

직접 구현하는 것도 코딩 실력에 도움이 되고, 라이브러리를 사용할 경우 공식 문서를 읽으며 빠르게 코드를 해석하는 능력도 기를 수 있습니다!

profile
FrontEnd Developer

0개의 댓글