2017-09-16 1 views
0

나는 색상에 대한 간단한 스크립트를느린 스크립트는

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
    <head> 
     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 
     <script src="http://code.jquery.com/jquery-latest.js"></script> 
     <title> 
      Click foto 
     </title> 
<style type="text/css"> 
/*<![CDATA[*/ 
html, body{ 
    height: 100%; 
} 

/*]]>*/ 
</style> 
    </head> 
    <body> 
    <div id="canvasDiv"> 
    </div> 
    </body> 

    <script> 
    var canvasDiv = document.getElementById('canvasDiv'); 
canvas = document.createElement('canvas'); 
canvas.setAttribute('width', 500); 
canvas.setAttribute('height', 500); 
canvas.setAttribute('id', 'canvas'); 
$(canvasDiv).prepend(canvas); 
if(typeof G_vmlCanvasManager != 'undefined') { 
    canvas = G_vmlCanvasManager.initElement(canvas); 
} 

var context = canvas.getContext('2d'); 
var imageObj = new Image(); 

imageObj.onload = function() { 
    $(canvas).attr({width : this.width, height: this.height}); 
    context.drawImage(imageObj,0,0); 
}; 
imageObj.src = 'cartina_italia.png'; 


    $('#canvas').click(function(e){ 
    console.time('click'); 
    mouseX = e.pageX - this.offsetLeft; 
    mouseY = e.pageY - this.offsetTop; 
     c = this.getContext('2d'); 
     p = c.getImageData(mouseX, mouseY, 1, 1).data; 
    hex = ("000000" + rgbToHex(p[0], p[1], p[2])).slice(-6); 
    console.timeEnd('click'); 
    console.time('selectArea'); 
    selectArea(mouseX,mouseY,c,hex); 
    console.timeEnd('selectArea'); 
    }); 

    function selectArea(x,y,c,color){ 
    if (x>=0 && y>=0){ 
     p = c.getImageData(x, y, 1, 1).data; 
     hex =("000000" + rgbToHex(p[0], p[1], p[2])).slice(-6); 

     if (color==hex){ 
     c.fillStyle = "rgba(255,0,0,0.1)"; 
     c.fillRect(x, y, 1, 1); 
     selectArea(x+1,y,c,color); 
     selectArea(x-1,y,c,color); 
     selectArea(x,y+1,c,color); 
     selectArea(x,y-1,c,color); 
     } 
     } 
    } 

function rgbToHex(r, g, b) { 
    if (r > 255 || g > 255 || b > 255) 
     throw "Invalid color component"; 
    return ((r << 16) | (g << 8) | b).toString(16); 
} 

    </script> 
</html> 

내가 테스트를 위해이 파일을 사용하고 같은 색의 픽셀과 모든 주변 픽셀을 만든 컬러에 대한 지역을 클릭하십시오 내가 느린 응답 (1000-5000ms), 첫 번째 3 번 후 50ms에서 함수 끝 문제를 표시하기 위해 jsfiddle을 사용할 수 없습니다. 기원전 원점 오류가 발생합니다.

코드는 클릭 한 픽셀의 색상을 변경하고 픽셀 색상이 전나무와 다를 때까지 가까운 픽셀에서 시작되는 간단한 재귀 함수입니다 st
하지만 왜 처음 3 번이 느린 응답을 가지고 있고 4 번째 이후에 0 지연이 있는지 이해할 수 없습니다 ....

+0

가 지금 주목 느린 성능 라인은 'p = c.getImageData (X, Y, 1,1) .DATA : 여기

는 예제 X 축은 더 빠르다. – Trigun

답변

1

구멍 이미지의 imageData를 캐싱하고 각 selectArea 호출에 getImageData을 호출합니다. 또한 최대 호출 스택 오류를 방지하기 위해 반복적으로 구현할 수도 있습니다. ;`후

var ExtendedCanvas = (function() { 
 
    var context, data, canvas; 
 
    function ExtendedCanvas(selector, imageSrc) { 
 
     var wrapper = document.querySelector(selector); 
 
     this.element = canvas = document.createElement('canvas'); 
 
     context = this.element.getContext('2d'); 
 
     loadImage.call(this, imageSrc, function(image) { 
 
      canvas.setAttribute('width', image.width); 
 
      canvas.setAttribute('height', image.height); 
 
      context.drawImage(image,0,0); 
 
      data = context.getImageData(0,0,canvas.width, canvas.height); 
 
     }); 
 
     wrapper.appendChild(this.element); 
 
    } 
 

 
    function loadImage(src, cb) { 
 
     var image = new Image(); 
 
     var canvas = this.element; 
 
     image.onload = function() { 
 
      cb(this); 
 
     } 
 
     image.crossOrigin = 'Anonymous'; 
 
     image.src = src; 
 
    } 
 

 
    ExtendedCanvas.prototype.getPixelIndex = function(x, y) { 
 
     return (Math.floor(y) * canvas.width + Math.floor(x)) * 4; 
 
    } 
 

 
    ExtendedCanvas.prototype.getPixelColor = function(x, y) { 
 
     var index = this.getPixelIndex(x, y); 
 
     var d = data.data; 
 
     var r = d[index]; 
 
     var g = d[index + 1]; 
 
     var b = d[index + 2]; 
 
     var a = d[index + 3]; 
 
     return [r, g, b, a]; 
 
    } 
 

 
    ExtendedCanvas.prototype.setPixelColor = function(x, y, color) { 
 
     var index = this.getPixelIndex(x, y); 
 
     var d = data.data; 
 
     d[index] = color[0]; 
 
     d[index + 1] = color[1]; 
 
     d[index + 2] = color[2]; 
 
     d[index + 3] = color[3]; 
 
    } 
 

 
    ExtendedCanvas.prototype.fill = function(x, y, fillColor) { 
 
     if(x < 0 || y < 0 || x > canvas.width || y > canvas.height) { 
 
      return; 
 
     } 
 
     fillColor = fillColor || [0,0,0,255]; 
 
     var stack = []; 
 
     var color = this.getPixelColor(x, y).join(); 
 

 
     if(color === fillColor) { 
 
      return; 
 
     } 
 

 
     stack.push([x, y]); 
 
     context.fillStyle = fillColor; 
 

 
     if(color === fillColor.join()) { 
 
      return; 
 
     } 
 
     while(stack.length > 0) { 
 
      var position = stack.pop(); 
 
      var posX = position[0]; 
 
      var posY = position[1]; 
 
      var posColor = this.getPixelColor(posX, posY).join(); 
 
      if(posColor === color) { 
 
       this.setPixelColor(posX, posY, fillColor); 
 
       stack.push([posX, posY + 1]); 
 
       stack.push([posX, posY - 1]); 
 
       stack.push([posX + 1, posY]); 
 
       stack.push([posX - 1, posY]); 
 
      } 
 
     } 
 
     context.putImageData(data, 0, 0); 
 
    } 
 

 
    return ExtendedCanvas; 
 
})(); 
 

 
document.addEventListener('DOMContentLoaded', function() { 
 
    var c = new ExtendedCanvas('#canvasWrapper', 'https://i.imgur.com/QWaKVGO.png'); 
 

 
    c.element.addEventListener('click', function(e) { 
 
     var x = e.pageX - this.offsetLeft; 
 
     var y = e.pageY - this.offsetTop; 
 
     c.fill(x, y); 
 
    }); 
 
});
<div id="canvasWrapper"></div>

+0

고마워 .--) 오늘 캔버스 태그를 발견하고 내 첫 시도였다. :-) 전체 영역을 얻으려면 getimagedata를 사용할 수 있다는 것을 몰랐다. Google 검색은 getImageData에서 나를 가리켰다. 그것을 사용하여 :-) – Trigun