Home 이미지-유효성-검사와-Compressor
Post
Cancel

이미지-유효성-검사와-Compressor

SNS서비스를 만드는 프로젝트를 하면서, 이미지를 처리해야 하는 경우가 많았다. 이미지 용량을 줄이는 compressor라이브러리 사용법과 file input에 대한 유효성 검사 함수를 정리했다.


1) 이미지 크기 제한

1
2
3
4
5
6
7
8
9
10
11
// 정해진 파일 크기보다 큰 파일이라면 false를 반환한다. (max: 최대 이미지 mb, fileSize: 업로드한 이미지 용량)
function checkImageSize(fileData: { max: number; fileSize: number }): boolean {
  const { max, fileSize } = fileData;

  // 제한되는 사이즈
  const maxSize = max * 1024 * 1024;
  if (maxSize <= fileSize) {
    return false;
  }
  return true;
}


2) 이미지 확장자 제한

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 정해진 파일 확장자가 아니라면 false를 반환한다. (fileName: 이미지 이름)
function checkImageExtension(fileName: string): boolean {
  // 이미지 확장자
  const imageExtensions = ["gif", "jpg", "jpeg", "png", "bmp", "ico", "apng"];

  // 업로드한 파일 확장자 ('.'이후의 문자를 소문자로 변환)
  const extension = fileName
    .substring(fileName.lastIndexOf(".") + 1)
    .toLocaleLowerCase();

  // 업로드한 파일 확장자가 이미지 확장자인지 확인한다. 
  const result = imageExtensions.some((item) => item === extension);

  return result;
}


3) 이미지 Compressor

compressor.js 공식 문서

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import Compressor from "compressorjs";

// 이미지 compressor (file: 업로드한 파일 )
function compressorImage(file: File): Promise<File> {
    
  // 프로미스 객체를 반환한다. 
  return new Promise((resolve, reject) => {
    new Compressor(file, {
      
      // compressor 옵션 
      checkOrientation: false,
      quality: 0.8,
      maxWidth: 1920,
      maxHeight: 1920,
        
      // compressor에 성공했을 경우, 파일로 저장하여 반환한다.  
      success(result: File) {
        const compressorImage = new File([result], result.name, {
          type: result.type,
        });
        resolve(compressorImage);
      },
      
      // compressor에 실패했을 경우, 
      error(error) {
        reject(error);
      },
    });
  });
}


4) 실제 적용 로직 (vue3)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
import {checkImageSize, compressorImage, checkImageExtension,} from "../../functions/image";

// fileInput의 change 이벤트가 발생할 때 실행한다. 
const changeCustomCocktailImage = (event: Event) => {
  let file = (event.target as HTMLInputElement).files![0];

  // 파일을 업로드 하지 않고 취소 버튼을 누르는 경우
  if (!file) {
    return;
  }

  // 업로드한 파일이 이미지가 아닌경우
  if (!checkImageExtension(file.name)) {
    store.dispatch(
      "modal/changeErrorModalMessage",
      "올바른 이미지 파일을 업로드 하세요."
    );
    store.dispatch("modal/blinkErrorModalAppStatus", true);
    return;
  }

  // 이미지 용량이 5mb초과면 compressor를 진행한다.
  if (!checkImageSize({ max: 5, fileSize: file.size })) {
    compressorImage(file).then((result) => {
        
      // compressor를 진행해도 이미지 용량이 10mb 초과면 알림을 보낸다. 
      if (!checkImageSize({ max: 10, fileSize: result.size })) {
        store.dispatch(
          "modal/changeErrorModalMessage",
          "이미지가 너무 큽니다."
        );
        store.dispatch("modal/blinkErrorModalAppStatus");
        return;
          
     // compressor를 진행 후, 이미지 용량이 10mb 이하면 업로드 한다. 
      } else {
        const data = {
          img: result,
        };
        store.dispatch("customCocktail/uploadImage", data);
        emit("changeImage", data.img);
        return;
      }
    });

    // 이미지 용량이 5mb 이하면 compressor 없이 그냥 업로드 한다.
  } else {
    const data = {
      img: file,
    };
    store.dispatch("customCocktail/uploadImage", data);
    emit("changeImage", data.img);
    return;
  }
};
  • event.target.files[0]을 통해 파일을 가져온다.
  • 만약 파일이 아니거나 이미지 파일이 아니면 바로 return 한다.
  • 이미지 파일이 5mb 초과면 compressor를 진행한다.
    • compressor를 진행해도 이미지가 10mb 초과이면 알림을 보내고 바로 return한다.
    • compressor를 진행 후, 이미지가 10mb 이하이면 파일을 서버에 보낸다.
  • 이미지 파일이 5mb 이하면 compressor 없이 바로 서버에 보낸다.
This post is licensed under CC BY 4.0 by the author.