[HTML5] Canvas로 색을 뽑아 보자

Mido·2023년 3월 16일
0
post-thumbnail

포토샵, 라이트룸 등의 이미지 보정 프로그램으로 특정 색을 강조하거나 흑백으로 만들기가 아주 쉽다. 그렇다면 웹 페이지로 그것을 구현이 가능할까?

<div id="Pics">
      <img id="myImage" src="https://upload.wikimedia.org/wikipedia/commons/thumb/c/c5/Colorwheel.svg/1200px-Colorwheel.svg.png" alt="x"></img>
      <canvas id="myCanvas"></canvas>
</div>

우선 html에 이미지를 삽입하고 바로 옆에 canvas 객체를 만들어주었다 canvas는 HTML5에서 추가된 말 그대로 그림을 그릴 수 있는 도화지와 같으며 다른 객체의 이미지를 복사하여 그려넣기도 가능하다.

var imageObj = document.getElementById("myImage");
    var canvas = imageObj.nextSibling;
    canvas.height = imageObj.height;
    canvas.width = imageObj.width;
    var ctx = canvas.getContext('2d');
    ctx.drawImage(imageObj, 0, 0, imageObj.width, imageObj.height);
    var id= ctx.getImageData(0, 0, imageObj.width, imageObj.height);

Id가 myImage인 객체의 엘레먼트를 받아서 imageObj변수에 넣었다.
그리고 nextSibling를 사용하여 imageObj의 다음에 있는 객체 즉 myCanvas를
변수 canvas에 넣었다.
다음으로는 canvas의 넓이와 높이를 imageObj와 동일하게 만들고
2d 그래픽을 다룰 것이므로 var ctx = canvas.getContext('2d') 캔버스를 2d로 정한다.

ctx.drawImage(imageObj, 0, 0, imageObj.width, imageObj.height);
var id= ctx.getImageData(0, 0, imageObj.width, imageObj.height);

이후에 ctx에 위와 같은 값으로 omageObj의 이미지를 그리고 그것을 픽셀 단위로 쪼개서
id에 저장한다.

for (var i = 0; i < id.data.length-4; i += 4) {
  
if(filter==="RED"){
  if((id.data[i+1]>id.data[i+2]+40) ||(id.data[i]-id.data[i+1])<10 || (id.data[i]-id.data[i+2])<25){
          id.data[i] = id.data[i+1] = id.data[i+2] = (id.data[i]+ id.data[i+1] + id.data[i+2])/3;
          //빨강 필터
  }
}
if(filter==="GREEN"){
  if((id.data[i+1]-id.data[i])<0|| (id.data[i+1]-id.data[i+2])<0 ||(id.data[i]>id.data[i+2]+150)){
    id.data[i] = id.data[i+1] = id.data[i+2] = (id.data[i]+ id.data[i+1] + id.data[i+2])/3;
          //초록 필터
  }
}
if(filter==="BLUE"){
  if( (id.data[i]-id.data[i+1])>30 || (id.data[i]>id.data[i+2]) || (id.data[i+2]<id.data[i+1]-0)) {
    id.data[i] = id.data[i+1] = id.data[i+2] = (id.data[i]+ id.data[i+1] + id.data[i+2])/3;
          //파랑 필터
  } 
}
if(filter==="YELLOW"){
  if((id.data[i+1]-id.data[i])<-20|| (id.data[i+1]-id.data[i+2])<0 || (id.data[i]-id.data[i+2])<30){
    id.data[i] = id.data[i+1] = id.data[i+2] = (id.data[i]+ id.data[i+1] + id.data[i+2])/3;
          //노랑 필터
  } 
}
}

리액트 state값에 따라 색상을 정하였으며
canvas위에 그려진 이미지를 픽셀단위로 쪼개 id에 저장하였는데
이는 RGBA순서로 4개씩 저장이 되므로 for문을 통해 for (var i = 0; i < id.data.length-4; i += 4)와 같이 4개의 i당 1개의 색을 가지므로 모든 픽셀을 검토할 수 있다.
특정 계열의 색상을 rgb로 단순히 구분하기는 매우 어려워 가능한 한 간단한 방식으로 직접 확인하며 조건을 정해주었다.

ctx.putImageData(id, 0, 0);

그리고 마지막에 이미지 데이터를 다시 캔버스 ctx에 넣어서 모든 픽셀을 조사하여 원하는 값을 변경한 결과물을 생산해낼 수 있다.


빨간색을 제외하고 흑백으로 만든 상태

빨간색을 제외하고 흑백으로 만든 상태

profile
Front-End

0개의 댓글