ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [javascript] server에 이미지 파일 전달하기 전에 용량 줄이기
    개발자의 공부는 은퇴까지 필수다/vue 2021. 11. 25. 17:45

    단계별로 이미지를 찍어서 서버쪽으로 제출하는 프로그램을 작업하고 있는 중에 제출 이미지가 늘어나니 간헐적으로 서버에서 응답이 너무 늦게와 응답을 보냈음에도 불구하고 프론트에서 못받는 문제가 발생했다.

    aws lambda에서는 5mb로 파라미터 용량을 제한하기도 하고, 이런저런 문제를 생각했을 때 프론트쪽에서 api 호출 전에 이미지 사이즈를 줄여 보내는 것이 가장 좋은 방안 같았다.

     

    video 에서 캡처해온 이미지의 용량을 줄이는 방법과 file input 으로 가져온 이미지의 용량을 줄이는 방법을 기록할 예정이다.

     

    보내는 파일 형식은 base64. canvas 를 이용해서 용량을 줄일 수 있다.

    적용 후 400kb였던 파일이 72kb까지 용량이 줄었고 화질은 육안으로 큰 차이가 없었다.

     

    1. video 에서 캡처해온 이미지의 용량을 줄이는 방법. 

    let video = document.querySelector('video');
    video.width = this.width*2;
    video.height = this.height*2;
    
    let canvas = document.querySelector("#canvas");
    let context = canvas.getContext('2d');
    
    context.imageSmoothingEnabled = false;
    context.webkitImageSmoothingEnabled = false;
    context.mozImageSmoothingEnabled = false;
    
    
    //캔버스에 그리기
    context.save();
    context.scale(-1, 1);// 좌우반전 (셀카모드이기 때문에 좌우반전을 했다.)
    context.translate(this.width*(-1), 0);
    context.drawImage(video, 0, 0, this.width, this.height);
    
    //캔버스로부터 실제 이미지를 가져오기
    //const imgUrl = canvas.toDataURL('image/png');
    
    //toDataURL의 뒤에 들어가는 파라미터 숫자(0.5)가 작아질 수록 화질이 떨어진다. 
    //사실 0.5까지는 육안으로 차이를 느끼지 못했다.
    let imgUrl = canvas.toDataURL('image/jpeg', 0.5);

     

    2. file input 으로 가져온 이미지 파일 용량 줄이기

    /**
    파일이 input 되면 일어나는 이벤트
    */
    //vue라서 refs로 가져오는데 document.getElementById와 같은 함수로 사용해도 됩니다.
    let file = this.$refs.localCam.files[0];
    let reader  = new FileReader();
    reader.addEventListener("load", function ( e ) {
    
      const image = new Image();
      image.src = e.target.result;
      image.onload = imageEvent => {
      // 이미지가 로드가 되면! 리사이즈 함수가 실행되도록 합니다.
      		vueObj.imageSizeChange(image);
    	};
    }, false);
    if (file) {
    	reader.readAsDataURL(file);
    }
    /**
    * image onload 에서 호출하는 imageSizeChange함수입니다.
    * 이미지 용량을 줄여 Param 에 담습니다
    */
        imageSizeChange( image ) {
    
          let canvas = document.createElement("canvas"),
              max_size = 1280,
              // 최대 기준을 1280으로 잡음.
              width = image.width,
              height = image.height;
          if (width > height) {
            // 가로가 길 경우
            if (width > max_size) {
              height *= max_size / width;
              width = max_size;
            }
          } else {
            // 세로가 길 경우
            if (height > max_size) {
              width *= max_size / height;
              height = max_size;
            }
          }
          canvas.width = width;
          canvas.height = height;
          canvas.getContext("2d").drawImage(image, 0, 0, width, height);
          this.imgUrl = canvas.toDataURL("image/jpeg", 0.5);
        },
Designed by Tistory.