이미지 크롭 기능 구현하기(blob, base64)

Mincho·2023년 7월 2일
0

cs지식

목록 보기
8/10

🔴 문제 상황

Curb프로젝트 진행 당시 게시물 사진을 업로드 하는데 문제점이 발생하였다. 클라이언트가 올리는 사진에 대해 특정한 사이즈가 요구 되는데 이 비율에 맞추지 못하면 이미지의 특정 영역을 보일 수가 없었기 때문이다. 이를 위해 다른 sns를 확인하면 이미지를 크롭하거나 잘라 업로드 할 수 있게 해놓았기 때문에 이를 참고하여 문제를 풀어나가려고 했다.



🟠 react-easy-crop

 react-easy-crop을 이용하면 어떠한 이미지 파일이든 호환이 가능하고 html5에서 지원하는 어떠한 형식이든 지원한다.

import React, { useState, useCallback } from 'react'
import ReactDOM from 'react-dom'
import Cropper from 'react-easy-crop'
import './styles.css'

const App = () => {
  const [crop, setCrop] = useState({ x: 0, y: 0 })
  const [zoom, setZoom] = useState(1)
  const onCropComplete = useCallback((croppedArea, croppedAreaPixels) => {
    console.log(croppedArea, croppedAreaPixels)
    //크롭 영역, 크롭 픽셀
  }, [])
  
  return (
    <div className="App">
      <div className="crop-container">
        <Cropper
          image={원하는 이미지 형식}
          crop={crop}
          zoom={zoom}
          aspect={4 / 3}
          onCropChange={setCrop}
          onCropComplete={onCropComplete}
          onZoomChange={setZoom}
        />
      </div>
      <div className="controls">
        <input
          type="range"
          value={zoom}
          min={1}
          max={3}
          step={0.1}
          aria-labelledby="Zoom"
          onChange={(e) => {
            setZoom(e.target.value)
          }}
          className="zoom-range"
        />
      </div>
    </div>
  )
}

  여기서 크롭을 하여 크롭된 사이즈값들을 받고 canvas에 그려주면 된다.

const [croppedArea, setCroppedArea] = useState<CropAttribute>({
   x: 0,
   y: 0,
   width: 0,
   height: 0,
 });

나의 경우 canvas에 그려줄 값의 x,y,width,height 속성을 상태로 저장해놓았다.



🟡 Canvas를 통해 이미지 크롭해주기

 Canvas는 vanilla JS상에서 DOM조작을 통해 그래픽 작업을 지원하는 api이다.

canvas method중 drawImage()를 이용하여 Crop한 이미지를 그릴 요소를 새로 만들어주면 된다.

 image변수에는 crop을 원하는 image를 저장하고. canvas를 이미지 형식이므로 2d형식으로 지정했다.
마지막으로 캔버스에 image변수와, width와 height값과 x축,y축으로 그려주었다. 이렇게 canvas에 그려준 img를 가져오기 위해서 dataURL방식으로 가져왔다.

🟢 데이터형식에서의 문제(base64, BLOB)

 Canvas에서 파일을 저장하는 형식은 Base64형식이다.
Base64형식은 바이너리 데이터를 ASCII 문자열 형태로 인코딩하는 방식이다. 이로 인해 이미지형식 등을 js 변수에 저장할 수 있었던 것이다.

jpg이미지를 다음과 같이 base64로 변환하였다. 보이듯이 Base64는 가독성이 좋지 않으며, 데이터의 양이 커지는 단점도 보인다.

 이미지 데이터를 서버에 전송하기 위해서는 Blob형식으로 처리해야 한다고 한다.Blob은 “Binary Large Object”의 약어로, 이진 데이터를 나타내는 자바스크립트 객체이다. 앞의 Base64형식인 문자열과 달리 객체 url이기 때문에 단순히 브라우저에서 사용할 수 있으며 여러가지 파일 형식으로 변환 가능하다.

 이를 위해 base64형식의 문자열 데이터를 Blob형식으로 바꾸고 jpeg형식의 파일로 지정해주었다.

🔵 결과화면



Reference
https://inpa.tistory.com/entry/JS-%F0%9F%93%9A-Base64-Blob-ArrayBuffer-File-%EB%8B%A4%EB%A3%A8%EA%B8%B0-%EC%A0%95%EB%A7%90-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0-%EC%89%BD%EA%B2%8C-%EC%84%A4%EB%AA%85

👍올바른 피드백은 언제든지 환영입니다~!

profile
사진찍는 개발자.

0개의 댓글