[Canvas]Canvas에서 사진을 다루기

maru5mango·2022년 4월 13일
0

After9

목록 보기
2/3

오늘의 미션

📌demo

  • 사진 업로드
  • 사진 비율이 깨지지 않게 Canvas에 그리기
  • 사진 위에 그림그리기
  • 해당 사진 다운로드 하기

1) 사진 업로드

  • input 태그에 파일을 업로드
  • e.target.files[0] FileBloB을 FileReader을 이용하여 readAsDataURL로 변환한다.
  • FileReader가 load되면 FileReader의 result값을 리턴한다.
const encodeBase64 = (file) => {
  const reader = new FileReader();
  reader.readAsDataURL(file);
  return new Promise((resolve) => {
    reader.onload = () => {
      resolve(reader.result);
    };
  });
};

const $upload = document.getElementById("uploadFile");
$upload.addEventListener("change", async (e) => {
  await upload(e.target.files[0]);
});

async function upload(file){
  const imgDataURL = await encodeBase64(file);
}

2) 사진 비율 깨지지 않게 Canvas에 그리기

  • 사진의 비율을 계산
  • Canvas의 비율을 계산
  • Canvas Width에 맞추어 사진을 그린다.
    (세로로 비율이 긴 사진은 무시한 예시입니다.)
async function upload(file) {
  const imgDataURL = await encodeBase64(file);
  const image = new Image();
  image.src = imgDataURL;
  image.onload = () => {
    const width = image.width;
    const height = image.height;
    const ratio = height / width;
    resultCanvas.drawImage(image, { width, height, ratio });
  };
}


canvas class {
  .....
  
  
  drawImage(img, imgSize) {
    const { width: imgWidth, height: imgHeight, ratio } = imgSize;

    const canvasWidth = this.$canvas.width;
    const canvasHeight = this.$canvas.height;

    const width = canvasWidth;
    const height = canvasWidth * ratio;
    this.ctx.drawImage(img, 0, 0, width, height);
  }

3) 사진 위에 그림 그리기

  • 마우스를 down -> move -> up 하는 것을 기준으로 down과 up에서 현재 그림 그리는 여부를 판단하고, move에서 Canvas에 그림을 그린다.
  • 그림을 그리는 것은 Canvas의 beginPath메소드를 사용한다.
class Canvas {
  ...
  setEvent() {
    const that = this;
    this.$canvas.addEventListener("mousemove", (e) => {
      const { offsetX, offsetY } = e;
      that.drawLine(offsetX, offsetY);
    });
    this.$canvas.addEventListener(
      "mousedown",
      this.startDrawing.bind(this)
    );
    this.$canvas.addEventListener("mouseup", this.endDrawing.bind(this));
  }

  drawLine(x, y) {
    if (!this.isDrawing) return;
    this.ctx.beginPath();
    this.ctx.arc(x, y, 10, 0, Math.PI * 2);
    this.ctx.closePath();
    this.ctx.fill();
  }
}

4) 해당 사진 다운로드 하기

  • 현재 canvas의 상태를 DataURL로 값을 얻는다.
  • a태그의 href에 dataUrl을 삽입한다.
  • a태그의 download 속성에 다운로드할 이름을 넣는다.
const $download = document.getElementById("download");
function download() {
  const image = resultCanvas
  .getDataURL()
  .replace("image/png", "image/octet-stream");
  $download.setAttribute("href", image);
  $download.setAttribute("download", "helloWorld.png");
}
$download.addEventListener(
  "click",
  (e) => (e.target.href = resultCanvas.getDataURL())
);

0개의 댓글