简体   繁体   English

画布油漆桶/洪水填充工具卡在循环中

[英]Canvas paint bucket/flood fill tool gets stuck in loop

I'm using the code from this tutorial .我正在使用本教程中的代码。 I'm also letting the user select the color using <input type="color"> (and I convert that to RGB since it returns a hex value).我还让用户使用<input type="color">选择颜色(我将其转换为 RGB,因为它返回一个十六进制值)。 The fill seems to work just fine if the color is left at the default (set to black on initialization).如果颜色保留为默认值(初始化时设置为黑色),填充似乎工作得很好。 If the color is changed using the input though, sometimes it ends up freezing.如果使用input更改颜色,有时它最终会冻结。 From what I can tell it gets stuck in this loop:据我所知,它陷入了这个循环:

while (pixelStack.length) {...}

There is a section in the loop where it pushes new values to the pixelStack array:循环中有一个部分将新值推送到pixelStack数组:

while (y++ < height - 1 && matchStartColor(pixelPos)) {
   colorPixel(pixelPos);
   if (x > 0) {
      if (matchStartColor(pixelPos - 4)) {
         if (!reachLeft) {
            pixelStack.push([x - 1, y]);
            reachLeft = true;
         }
      } else if (reachLeft) {
            reachLeft = false;
         }
   }

   if (x < width - 1) {
      if (matchStartColor(pixelPos + 4)) {
         if (!reachRight) {
            pixelStack.push([x + 1, y]);
            reachRight = true;
         }
      } else if (reachRight) {
            reachRight = false;
        }
      }
      pixelPos += width * 4;
   }

As I understand this, the only reason it would constantly push to the pixelStack array is if the matchStartColor function never came back false.据我了解,它不断推送到pixelStack数组的唯一原因是matchStartColor函数永远不会返回 false。

function matchStartColor(pixelPos) {
   var r = imageData.data[pixelPos];
   var g = imageData.data[pixelPos + 1];
   var b = imageData.data[pixelPos + 2];

   return (r && g && b);
}

But I don't see why this sometimes works and other times not.但我不明白为什么这有时会起作用,而有时却不起作用。

Basically the pixelStack array ends up growing continually so it can never exit the loop.基本上pixelStack数组最终会不断增长,因此它永远不会退出循环。 I made a jsFiddle with a working example (though it will lock up eventually if you change the color and try to fill).我用一个工作示例制作了一个jsFiddle (尽管如果您更改颜色并尝试填充它最终会锁定)。 It doesn't seem to fail 100% of the time when the color is changed, but change the color enough and fill and it eventually does (and some colors seem to fail more than others. The pinkish/red in the top left of the color picker window is a bad one for example).当颜色改变时,它似乎不会 100% 失败,但是改变颜色并填充它最终会成功(有些颜色似乎比其他颜色更失败。左上角的粉红色/红色例如,颜色选择器窗口是一个糟糕的窗口)。

It seems your issue is in your implementation of matchStartColor .您的问题似乎出在matchStartColor的实现中。

With the following implementation:使用以下实现:

function matchStartColor(pixelPos) {
    var r = imageData.data[pixelPos];
    var g = imageData.data[pixelPos + 1];
    var b = imageData.data[pixelPos + 2];

    return (r && g && b);
}

This will only ever return false if either r , g or b are 0. When you use black (or any color with a 0 component), this works.如果rgb为 0,这只会返回 false 。当您使用黑色(或任何具有 0 分量的颜色)时,这是有效的。 If you pick a color where none of the components are 0, this function never returns false.如果您选择的颜色的所有分量都不为 0,则此函数永远不会返回 false。

I think what you actually want to do here is compare the color of the image to the color that you've chosen.我认为您在这里真正想做的是将图像的颜色与您选择的颜色进行比较。

Based on how you use this function, I think this should work:根据您如何使用此功能,我认为这应该有效:

function matchStartColor(pixelPos) {
    var r = imageData.data[pixelPos];
    var g = imageData.data[pixelPos + 1];
    var b = imageData.data[pixelPos + 2];

    return (r !== curColor.r || g !== curColor.g || b !== curColor.b);
} 

https://jsfiddle.net/6Uy3U/4/ https://jsfiddle.net/6Uy3U/4/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM