Javascript 洪水填充算法

Javascript 洪水填充算法,javascript,canvas,ecmascript-6,html5-canvas,Javascript,Canvas,Ecmascript 6,Html5 Canvas,我正在使用泛洪填充算法,但速度非常慢。例如,我有画布(512px 512px),要填满整个画布需要6秒钟。你能帮我改进我的实施吗?我使用的是来自 这里是我试图改进算法的链接: 函数泛洪(上下文、画布、颜色、目标){ 功能泛光填充(startX、startY、彩色){ 函数isStartColor(位置、起始颜色、图像数据){ 如果((图像数据[position+0])!=((startColor>>24)和0xFF) ||(图像数据[位置+1])!=((起始颜色>>16)和0xFF) ||(图

我正在使用泛洪填充算法,但速度非常慢。例如,我有画布(512px 512px),要填满整个画布需要6秒钟。你能帮我改进我的实施吗?我使用的是来自

这里是我试图改进算法的链接:

函数泛洪(上下文、画布、颜色、目标){
功能泛光填充(startX、startY、彩色){
函数isStartColor(位置、起始颜色、图像数据){
如果((图像数据[position+0])!=((startColor>>24)和0xFF)
||(图像数据[位置+1])!=((起始颜色>>16)和0xFF)
||(图像数据[position+2])!=((startColor>>8)和0xFF)){
返回false;
} 
返回true;
}
函数drawPixel(位置、图像数据){
imageData[位置]=color.r;
imageData[位置+1]=颜色.g;
imageData[位置+2]=颜色b;
图像数据[位置+3]=255;
}
让堆栈=[[startX,startY]];
while(堆栈长度){
const image=context.getImageData(0,0,canvas.width,canvas.height);
常量imageData=image.data;
const newPosition=stack.pop();
常数x=数学圆(newPosition[0]);
常数y=数学圆(newPosition[1]);
常量像素位置=(y*canvas.width+x)*4;
常数startColor={
r:imageData[像素位置+0]{
如果(!target.classList.contains('active-tool')){
返回
}
泛光填充(event.offsetX/xCoordinateScale、event.offsetY/yCoordinateScale、泛光颜色);
});
}

在您的代码中移动
const image=context.getImageData(0,0,canvas.width,canvas.height);
上一行,而
context.putImageData(image,0,0);
在关闭
后向下一行
当然,你会看到一个巨大的改进谢谢,它提高了我的算法的性能,解决了我的问题。
function flood(context, canvas, color, target) {

      function floodFill(startX, startY, color) {

        function isStartColor(position, startColor, imageData) {
          if ((imageData[position + 0]) != ((startColor >> 24) & 0xFF)
                  || (imageData[position + 1]) != ((startColor >> 16) & 0xFF)
                  || (imageData[position + 2]) != ((startColor >> 8) & 0xFF)) {  
                    return false;     
                } 
                return true;
        }

        function drawPixel(position, imageData) {
          imageData[position] = color.r;
          imageData[position + 1] = color.g;
          imageData[position + 2] = color.b;
          imageData[position + 3] = 255;
        }

        let stack = [[startX, startY]];

        while (stack.length) {
          const image = context.getImageData(0, 0, canvas.width, canvas.height);
          const imageData = image.data;
          const newPosition = stack.pop();
          const x = Math.round(newPosition[0]);
          const y = Math.round(newPosition[1]);

          const pixelPosition = (y * canvas.width + x) * 4;

          const startColor = {
            r: imageData[pixelPosition + 0] << 24,
            g: imageData[pixelPosition + 1] << 16,
            b: imageData[pixelPosition + 2] << 8
          }

          while (y-- >= 0 && isStartColor(pixelPosition, startColor, imageData)) {
            pixelPosition = pixelPosition - canvas.width * 4;
          }

          y++;
          pixelPosition = pixelPosition + canvas.width * 4;
          let reachLeft = false;
          let reachRight = false;

          while (y++ < canvas.height - 1 && isStartColor(pixelPosition, startColor, imageData)) {
            drawPixel(pixelPosition, imageData);

            if (x > 0) {
              if (isStartColor(pixelPosition - 4, startColor, imageData)) {
                if (!reachLeft) {
                  stack.push([x - 1, y]);
                  reachLeft = true;
                }
              } else {
                if (reachLeft) {
                  reachLeft = false;
                }
              }
            }

          if (x < canvas.width - 1) {
              if (isStartColor(pixelPosition + 4, startColor, imageData)) {
                if (!reachRight) {
                  stack.push([x + 1, y]);
                  reachRight = true;
                }
              } else {
                if (reachRight) {
                  reachRight = false;
                }
              }
            }
            pixelPosition = pixelPosition + canvas.width * 4;
          }

          context.putImageData(image, 0, 0);
        }
      }


      const canvasHTMLWidth = document.querySelector('.main-canvas').offsetWidth;
      const canvasHTMLHeight = document.querySelector('.main-canvas').offsetHeight;
      let xCoordinateScale;
      let yCoordinateScale;

      function getCoodinateScale() {
          xCoordinateScale = (canvasHTMLWidth / canvas.width);
          yCoordinateScale = (canvasHTMLHeight / canvas.height);
        }

        function hexToRgb(hex) {
            var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
            return result ? {
              r: parseInt(result[1], 16),
              g: parseInt(result[2], 16),
              b: parseInt(result[3], 16),
              a: 255
            } : null;
          }

        getCoodinateScale();
        const floodColor = hexToRgb(color.value);
        canvas.addEventListener('mousedown', (event) => {
          if (!target.classList.contains('active-tool')) {
            return
          }
          floodFill(event.offsetX / xCoordinateScale, event.offsetY / yCoordinateScale, floodColor);
        });
    }