最近,我一直在尝试创建代码来用颜色填充任何形状的多边形。我已经能够正确填充只有一个边框大小的线条的形状,尽管我发现自己无能为力。问题是代码不知道何时考虑将大于预期的像素线作为形状的垂直或水平边框。我从左到右遍历形状的每个像素,并通过检查 alpha 值是否为 0 来检查任何像素是否具有任何形式的颜色。一旦它找到一个 alpha 值不为 0 的像素,它向前移动一个像素,然后使用偶数/奇数技术来确定该点是否在多边形的一部分内(它在右侧制作一条无限线并确定与彩色线的碰撞次数是否为奇数,并且如果是,则该点位于多边形内)。一般来说,我们认为一个单独的像素算作一条线,我们认为多于一个像素的水平线是两条线,因为水平线是否经常成为边框的一部分。采取以下场景:
在这里,红点是我们开始测试的点(像素)。如果我们不认为中间的水平线是两个点(如红线和 x 所示),我们将只有两个交点,因此不会填充像素,尽管我们肯定会这样做想要填充那个像素。然而,如前所述,这带来了另一个不同场景的问题:
在这种情况下,如果我们确实将超过一个像素的水平线算作两条单独的线,我们最终不会填充任何边框比预期粗细的区域。供您参考,处理此问题的函数如下:
//imgData is essentially a WebImage object (explained more below) and r, g, and b are the color values for the fill color
function fillWithColor(imgData, r, g, b) {
//Boolean determining whether we should color the given pixel(s) or not
var doColor = false;
//Booleans determining whether the last pixel found in the entire image was colored
var blackLast = false;
//Booleans determining whether the last 1 or 2 pixels found after a given pixel were colored
var foundBlackPrev, foundBlackPrev2 = false;
//The number of colored pixels found
var blackCount = 0;
//Loop through the entire canvas
for(var y = 0; y < imgData.height; y += IMG_SCALE) {
for(var x = 0; x < imgData.width; x += IMG_SCALE) {
//Test if given pixel is colored
if(getAlpha(imgData, x, y) != 0) {
//If the last pixel was black, begin coloring
if(!blackLast) {
blackLast = true;
doColor = true;
}
} else {
//If the current pixel is not colored, but the last one was, find all colored lines to the right
if(blackLast){
for(var i = x; i < imgData.width; i += IMG_SCALE) {
//If the pixel is colored...
if(getAlpha(imgData, i, y) != 0) {
//If no colored pixel was found before, add to the count
if(!foundBlackPrev){
blackCount++;
foundBlackPrev = true;
} else {
//Otherwise, at least 2 colored pixels have been found in a row
foundBlackPrev2 = true;
}
} else {
//If two or more colored pixels were found in a row, add to the count
if(foundBlackPrev2) {
blackCount++;
}
//Reset the booleans
foundBlackPrev2 = foundBlackPrev = false;
}
}
}
//If the count is odd, we start coloring
if(blackCount & 1) {
blackCount = 0;
doColor = true;
} else {
//If the last pixel in the entire image was black, we stop coloring
if(blackLast) {
doColor = false;
}
}
//Reset the boolean
blackLast = false;
//If we are to be coloring the pixel, color it
if(doColor) {
//Color the pixel
for(var j = 0; j < IMG_SCALE; j++) {
for(var k = 0; k < IMG_SCALE; k++) {
//This is the same as calling setRed, setGreen, setBlue and setAlpha functions from the WebImage API all at once (parameters in order are WebImage object equivalent, x position of pixel, y position of pixel, red value, green value, blue value, and alpha value)
setRGB(imgData, x + j, y + k, r, g, b, 255);
}
}
}
}
}
}
//Update the image (essentially the same as removing all elements from the given area and calling add on the image)
clearCanvas();
putImageData(imgData, 0, 0, imgData.width, imgData.height);
//Return the modified data
return imgData;
}
在哪里...
imgData是给定区域中所有像素的集合(本质上是一个 WebImage 对象)
IMG_SCALE是图像被放大的整数值(它也为我们提供了像素的比例)。在此示例中,它等于 4,因为图像放大到 192x256(从 48x64)。这意味着您在图像中看到的每个“像素”实际上都由一个 4x4 的相同颜色像素块组成。
所以,我在这里真正要寻找的是一种方法来确定一个给定的彩色像素是否是水平边框的一部分,或者它是否只是包含垂直边框厚度的另一块。此外,如果我通常对这个问题有错误的方法,我将非常感谢有关如何更有效地做到这一点的任何建议。谢谢你。