리액트 이미지 업로드 or 리액트 이미지 다중 업로드를 검색 하면 글이 많이 나오는데
소스가 모두 제각각이고 설명이 이해하기 힘들어서 여기저기서 소스를 짜집기해서 기능을 구현하고
다음 프로젝트에서 사용하기위해 훅으로 뺐다.
browser-image-compression 설치
npm i browser-image-compression
browser-image-compression
Compress images in the browser. Latest version: 2.0.0, last published: 7 months ago. Start using browser-image-compression in your project by running `npm i browser-image-compression`. There are 95 other projects in the npm registry using browser-image-com
www.npmjs.com
이미지 파일을 압축할때 사용할 라이브러리 입니다.
해당 훅을 사용하려면 browser-image-compression을 다운 받아야합니다.
import { useState } from "react";
//이미지 압축 라이브러리
import imageCompression from "browser-image-compression";
//limitCount 파일갯수제한
//isComp 압축 여부 true :이미지 압축 , false:이미지 압축안함
//imgMaxSize 압축 최대 크기 기본값1mb
//imgMaxWidthHeight 압축 이미지 최대 width,height 기본값1920px
const useImgUpload = (limitCount = 0, isComp = false, imgMaxSize = 1, imgMaxWidthHeight = 1920) => {
//이미지 파일 & 프리뷰URL useState
const [imgFiles, setImgFiles] = useState([]);
const [imgUrls, setImgUrls] = useState([]);
//이미지 가져오기 핸들러
const handler = (e) => {
//파일 가져오기
const files = e.currentTarget.files;
//state 초기화
setImgFiles([]);
setImgUrls([]);
//파일 갯수 제한
if (limitCount > 0) {
if ([...files].length > limitCount) {
alert(`이미지는 최대 ${limitCount}개까지 업로드가 가능합니다.`);
return;
}
}
//선택한 이미지 파일 반복문 돌리기
[...files].forEach(file => {
//이미지 파일만 올릴수 있게 체크
if (!file.type.match("image/.*")) {
alert('이미지 파일만 업로드가 가능합니다.');
return;
}
//압축 옵션
const options = {
maxSizeMB: imgMaxSize,
maxWidthOrHeight: imgMaxWidthHeight,
useWebWorker: true,
};
if (isComp) {
//이미지 압축
imageCompression(file, options)
.then((res) => {
//압축 이미지 파일 담기
//blob to file blob을 file로 형변환
setImgFiles(imgs => [...imgs, new File([res], res.name, { type: "image/" + res.name.split(".")[1] })]);
//압축 이미지 url 담기
const reader = new FileReader(); // FileReader API로 이미지 인식
reader.onload = () => {// 사진 올리고 나서 처리하는 event
setImgUrls(imgUrls => [...imgUrls, reader.result]);
};
reader.readAsDataURL(res); //reader에게 file을 먼저 읽힘
})
.catch((error) => {
console.log("파일 압축 실패", error);
})
} else {
//이미지 파일 담기
setImgFiles(imgs => [...imgs, file]);
//압축 이미지 url 담기
const reader = new FileReader(); // FileReader API로 이미지 인식
reader.onload = () => {// 사진 올리고 나서 처리하는 event
setImgUrls(imgUrls => [...imgUrls, reader.result]);
};
reader.readAsDataURL(file); //reader에게 file을 먼저 읽힘
}
});
}
return [imgFiles, imgUrls, handler];
};
export default useImgUpload;
useImgUpload라는 이름으로 훅을 만들었다.
사용법
import useImgUpload from ".../hooks/useImgUpload";
const [files, fileUrls, uploadHandle] = useImgUpload(5, true, 0.3, 1000);
<input
type="file"
accept="image/*"
multiple
onChange={uploadHandle}
/>
- 훅을 임포트 한다.
- 어떤 형태로 저장 할지 매개변수로 옵션을 설정하고 변수명을 짓는다.
- 매개변수1 ( 파일갯수 default=0 )
- 매개변수2 (압축 여부 default=false )
- 매개변수3 (압축 크기 default=1(mb) )
- 매개변수4 (최대 이미지 크기 default=1000(px) )
- file타입의 input태그에 onChange 함수에 선언했던 핸들러를 쓴다.
이렇게 사용하면 input태그를 클릭하여 이미지 파일을 선택하면
files에는 실제 파일이 담기고
fileUrls에는 이미지의 프리뷰가 담긴다.
'trouble shooting' 카테고리의 다른 글
이미지 업로드를 위한 파이어 스토리지 사용내용 (1) | 2023.07.31 |
---|---|
React AWS EC2 배포하기 (0) | 2022.11.03 |
React Redux toolkit 미들웨어 이해하기 (0) | 2022.10.26 |
redux-toolkit 콘솔에 상태값이 proxy로 찍힐때 (0) | 2022.10.18 |
React실행 에러 (0) | 2022.10.14 |