본문 바로가기
제가 쓴 책/HTML5, CSS3 and JavaScript

칼라 이미지를 Grayscale 이미지로 나타내기

by edupicker(체르니) 2013. 8. 8.

칼라 이미지를 Grayscale 이미지로 나타내기



Grayscale이란 검은색(black)과 흰색(White)의 중간색인 회색(Gray)의 색상으로 이미지를 표현하는 것으로 빛의 강도(Intensity)를 기준으로 하며 0부터 255까지 즉, 256 단계로 검정색(0)과 흰색(255)을 표현하고 중간 단계인 128은 회색으로 표현합니다.
그래서 RGB 칼라 이미지를 Grayscale 형태의 이미지로 나타내기 위해서는 jQuery 같은 편리한 JavaScript 라이브러리를 이용하면 grayscale() 함수를 이용하여 처리하면 되겠지만 여기서는 순수 javascript를 이용하여 그 기능을 구현하는 방법에 대해서 소개합니다.

RGB
색상값을 Gray 색상으로 바꾸는 방법은 다양한 형태가 존재하는데 가장 단순한 형태는 RGB 각각에 값들을 더하여 3으로 나눈 값을 이용하는 방법을 사용하면 편리합니다.


Grayscalecolor =(red+green+blue)/3


다음으로 아날로그 방송 시스템에서 사용되는 컬러 인코딩 방식인 PAL(Phase-Alternating Line)이나 우리나라, 미국 등에서 아날로그 방송에서 사용되는 NTSC(National Television System Committee)에서 사용하는 방법은 다음과 같은 계산된 계수를 이용합니다.


Grayscalecolor =0.299R + 0.587G+0.114B


위에서 R(Red), G(Rreen), B(Blue)를 나타냅니다.
ATSC(Advanced Television Systems Committee)
에 의해 개발된 HDTV에서 사용되는 방법은 다음과 같은 계산된 계수를 이용하여 이루어집니다.


Grayscalecolor =0.2126R + 0.7152G+0.0722B


위에서 사용한 계수들에 대한 사항은 “http://en.wikipedia.org/wiki/Grayscale”을 참고하였습니다.
이제 칼라 이미지를 Grayscale 이미지로 나타내볼까요? 먼저 “basic.html” 파일을 열어서 “// canvas에 그릴 선이나 도형 작성다음에 아래와 같이 작성합니다.


<!DOCTYPE HTML>
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=ko">
  <title>
칼라 미이지를 흑백 이미지로 나타내기</title>
  <style> canvas { border: 1px solid red; } </style>
  <script type=”text/javascript”>
    window.onload = function() {
      var canvas = document.getElementById("yourcanvas");
      var context = canvas.getContext("2d");
      // canvas
에 그릴 선이나 도형 작성

      var imageObj = new Image();
      imageObj.src = "WashingtonUniv.png";
      imageObj.onload = function() {
        var sw = canvas.width;
        var sh = canvas.height;

        //canvas
에 원래 크기의 1/2로 이미지 그리기
        context.drawImage(imageObj, 0, 0, sw, sh );
    }
  </script>
</head>
<body>
  <canvas id="yourcanvas" width="400" height="300"></canvas>
</body>
</html>

이와 같이 작성한 후 “RGBtoGrayImage.html”로 저장한 후 웹 브라우저를 통해 웹서버에 연결하며 보면 다음과 같이 원래 이미지의 1/2 크기의 RGB 색상으로 나타나게 됩니다.



이제 “context.drawImage(imageObj, 0, 0, sw, sh );” 다음 라인에 기존 이미지의 이미지 데이터를 추출하여 Gray 색상으로 바꾸고 다시 이를 적용하는 코드를 아래와 같이 작성합니다.

        //getImageData()
메서드를 이용하여 canvas에 그려진 이미지 데이터 얻기
        var imageData = context.getImageData(0, 0, sw, sh);
        var data = imageData.data;
       
        for(var i = 0; i<data.length; i+=4){
          var graysN =( data[i] + data[i+1] + data[i+2] ) /3;
          data[i]= graysN;
          data[i+1]= graysN;
          data[i+2]= graysN;
        }
      
       context.putImageData(imageData, 0, 0);
     }


위에서 image.data로부터 가져온 data 변수에는 배열 형태로 나타나며 Red, Green, Blue, Alpha 형태로 값을 가지고 있습니다. 따라서 위와 같이 for문 작업을 수행하며 Alpha값은 불투명도를 나타내므로 grayscale 작업에 직접적인 관련이 없으므로 코드 상에서 제외를 하였습니다.
이와 같이 작성한 후 변경 사항을 저장한 후 다시 웹 브라우저를 통해 웹서버에 연결하며 보면 다음과 같이 Gray 색상으로 나타나게 됩니다.



특정 영역만 Grayscale 형태로 바꾸기
Color
이미지의 특정 영역만 grayscale 형태로 바꾼다면 위 코드에서 아래와 같이 해당 코드를 바꿉니다.

var imageData = context.getImageData(0, 0, sw, sh);
var imageData = context.getImageData(100, 150, sw/2, sh/2);

, 이미지 데이터를 가져오는 위치가 (100,150) 에서 canvas 너비(width), 높이(height)의 절반 크기 만큼을 가져오도록 하고 이를 grayscale 형태로 바꾸도록 합니다.
그 다음 실제로 해당 영역에 적용하기 위해서 putImageData()  부분을 다음과 같이 수정합니다.

context.putImageData(imageData, 0, 0);
context.putImageData(imageData, 100, 150);

이제 모든 코드 수정이 끝났으므로 저장한 후 다음과 같이 해당 영역만 설정한 대로 Gray 색상으로 나타나게 됩니다.




불투명도를 나타내는 Alpha 값을 이용하여 화면을 희미하게 하기
pixel
값으로 0은 완전히 투명한 상태를 나타내며 128은 반투명은 255 100% 불투명함을 나타냅니다. 따라서 방금 전 이미지를 조금 희미하게 보이게 하기 위해서 for 문 안에 다음과 같은 코드 다음에 한 줄 코드를 추가해봅니다.

data[i+2]= graysN;
data[i+3]= 128;

저장한 후 보면 다음과 같이 반투명상태로 이미지가 보이게 됩니다.



이상으로 칼라 이미지에 grayscale을 전체 이미지에 혹은 이미지의 특정 위치에 적용하는 방법을 알아보았습니다.



- 본 저작물은 본인이 2011년 상반기부터 2012년 여름 즈음까지 도서 출판을 목적으로 약 470 페이지(A4, 폰트 10)으로 작성한 원본으로 2012년 10월 31일 출판 계약 이루어졌으나 출판사에서 약속한 출판일에 출판이 이루어지지 않아서 여러 번 출판 의사를 물었고 2013 4 월경 반드시 출간된다는 확답을 들은 후 추가 원고작업으로 작성한 것으로 출처가 명시된 이미지를 제외한 본 저작물에 대한 모든 권리는 본인(원철연)에서 있음을 알립니다.
개인적인 학습 목적으로 사용을 허용하며 온오프라인의 베포나 펌상업적인 용도의 사용은 삼가해주시기 바랍니다. 끝으로 학교나 비영리 단체에서의 경우 본 저작물을 비상업적인 용도로 활용하고자 할 경우 연락처를 비밀댓글로 남겨주시면 연락드리겠습니다.