2016-09-05 2 views
2

오늘 (사용 jQuery를하지 않고) 작동 방법 자바 스크립트 그레이 스케일 알고리즘을 이해하고, 그 결과는 내가 다음 문서를 발견 긴 검색되지 않습니다내가 그레이 스케일로 컬러 이미지를 변환하는 알고리즘을 찾고 있었다

3 Ways to Turn Web Images to Grayscale

이 문서에서는 다음과 같은 코드가 대체 초대 댓글이 문서 http://www.ajaxblender.com/howto-convert-image-to-grayscale-using-javascript.html에서 또한

var imgObj = document.getElementById('js-image'); 

function gray(imgObj) { 
    var canvas = document.createElement('canvas'); 
    var canvasContext = canvas.getContext('2d'); 

    var imgW = imgObj.width; 
    var imgH = imgObj.height; 
    canvas.width = imgW; 
    canvas.height = imgH; 

    canvasContext.drawImage(imgObj, 0, 0); 
    var imgPixels = canvasContext.getImageData(0, 0, imgW, imgH); 

    for (var y = 0; y < imgPixels.height; y++) { 
     for (var x = 0; x < imgPixels.width; x++) { 
      var i = (y * 4) * imgPixels.width + x * 4; 
      var avg = (imgPixels.data[i] + imgPixels.data[i + 1] + imgPixels.data[i + 2])/3; 
      imgPixels.data[i] = avg; 
      imgPixels.data[i + 1] = avg; 
      imgPixels.data[i + 2] = avg; 
     } 
    } 
    canvasContext.putImageData(imgPixels, 0, 0, 0, 0, imgPixels.width, imgPixels.height); 
    return canvas.toDataURL(); 
} 

imgObj.src = gray(imgObj); 

을 니펫을 포함

for (var y = 0; y < imgPixels.height; y++) { 
    for (var x = 0; x < imgPixels.width; x++) { 
     var i = (y * 4) * imgPixels.width + x * 4; 
     var avg = (imgPixels.data[i] + imgPixels.data[i + 1] + imgPixels.data[i + 2])/3; 
     imgPixels.data[i] = avg; 
     imgPixels.data[i + 1] = avg; 
     imgPixels.data[i + 2] = avg; 
    } 
} 

JSFiddle https://jsfiddle.net/n6q9a2c9/

for (var i = 0; i < imgPixels.data.length; i = i + 4) { 
    var avg = (imgPixels.data[i] + imgPixels.data[i + 1] + imgPixels.data[i + 2])/3; 
    imgPixels.data[i] = avg; 
    imgPixels.data[i + 1] = avg; 
    imgPixels.data[i + 2] = avg; 
} 

데모와

그리고 나는이 알고리즘이 작동하는 방법의 이해에 약간의 문제가있다. 이 코드에서

내가 var avg = (imgPixels.data[i] + imgPixels.data[i + 1] + imgPixels.data[i + 2])/3 우리가 4 씩 증가 왜 날 여기

for (var i = 0; i < imgPixels.data.length; i = i + 4) { 

에 혼란 부분 아래 공식 (R + G + B)/3되는 것을 이해

for (var i = 0; i < imgPixels.data.length; i = i + 4) { 
    var avg = (imgPixels.data[i] + imgPixels.data[i + 1] + imgPixels.data[i + 2])/3; 
    imgPixels.data[i] = avg; 
    imgPixels.data[i + 1] = avg; 
    imgPixels.data[i + 2] = avg; 
} 

스 니펫?

이 알고리즘의 작동 원리에 대해 답변 해 주시면 감사하겠습니다.

답변

2

캔버스 데이터는 RGBA (빨강, 녹색, 파랑 및 투명도 값 '알파'라고 함) 인터리브 형식으로 제공됩니다. 각 채널에는 픽셀 당 바이트가 필요하며 채널이 4 개이므로 픽셀 당 4 개의 값이 있습니다. 채널이 인터리브되므로 픽셀을 단계별로 4 씩 증가시킵니다.

참고 :

+0

감사합니다. 그 후 (jsfiddle에서)'console.log (imgPixels)'을 사용하여 많은 양의 데이터 배열을 얻으려고 시도했다. 그리고 console.log (imgPixels.data.length)로 666000 번을 얻는다. 이미지가'500px * 333px'이면이 번호를 얻는 방법 – Mikhail

+0

@Mikhail 500 * 333 * 4 = 666000 – Ouroborus

+1

오. 나는 내가 이해했다고 생각한다. '500 * 333 = 166500'이고 각 픽셀마다 4 개의 채널 (RGBA)이 있기 때문에'166500 * 4 = 666000'을 곱하면됩니다. – Mikhail

관련 문제