绘图应用flood fill泛洪填充功能左侧像素漏填行问题求助
问题根因
你当前的泛洪填充逻辑存在3个明确的bug,共同导致了左侧跳行的问题:
- 扫描线向下遍历的末尾错误填充了不符合条件的像素,污染了相邻列的颜色判断
- 右侧x坐标边界判断逻辑错误,可能读取到画布外的无效像素
- 未处理alpha通道的颜色匹配,存在隐性判断误差
1. 错误填充无效像素的问题
你在底部循环的判断逻辑里,y自增后如果判定当前像素不符合填充条件,仍然执行了一次drawFill操作,会把边界外/颜色不匹配的像素强制填充为目标色。当左侧列的扫描线遍历到这个被错误填充的像素时,matchColor会判定颜色不匹配,直接中断填充,最终表现为跳过一行。
原错误代码片段:
drawFill(canvas, x, y); y++; if(y >= canvasHeight || matchColor(canvas, x, y, startR, startG, startB) == false) { drawFill(canvas, x, y); // 这里的y已经不符合填充要求,属于误填充 bottom = true; }
修正方案:删除额外的drawFill调用,只填充符合条件的像素。
2. 右侧边界判断错误
画布的合法x坐标范围是0 ~ canvasWidth-1,你当前判断x+1 > canvasWidth才禁用右侧校验,会导致x+1 = canvasWidth时仍然读取画布外的像素,getImageData读取越界坐标会返回全0的透明像素,导致颜色匹配逻辑出错。
原错误代码片段:
if(x+1 > canvasWidth) { right = false; }
修正方案:改为判断x+1 >= canvasWidth。
3. 颜色匹配未判断alpha通道
你当前的matchColor只对比了RGB三个通道,未判断alpha值,如果画布上存在半透明像素,会出现匹配误差。建议补充alpha通道的校验。
完整修正后代码
//===== Fill Bucket Function =====\\ //----- Fill Call Function -----\\ var fill = function(canvas, startPosX, startPosY) { var startColor = canvas.getImageData(startPosX, startPosY, 1, 1).data; var startR = startColor[0], startG = startColor[1], startB = startColor[2], startA = startColor[3]; // 补充alpha通道读取 var currentColor = hexToRgb(selectedColor); if(currentColor.r == startR && currentColor.g == startG && currentColor.b == startB && startA === 255) { return; } var x = startPosX, y = startPosY; var pixelPos = [x, y]; while(pixelPos.length) { y = pixelPos.pop(); x = pixelPos.pop(); var top = false; while(top == false) { y--; if(y < 0 || !matchColor(canvas, x, y, startR, startG, startB, startA)) { top = true; y += 1; // 移除冗余的push/pop操作,直接赋值y } } var bottom = false, right = true, left = true; if(x-1 < 0) { left = false; } if(x+1 >= canvasWidth) { // 修正右侧边界判断 right = false; } while(bottom == false) { if(left && matchColor(canvas, x-1, y, startR, startG, startB, startA)) { left = false; pixelPos.push(x-1, y); }else if(!left && !matchColor(canvas, x-1, y, startR, startG, startB, startA)) { left = true; } if(right && matchColor(canvas, x+1, y, startR, startG, startB, startA)) { right = false; pixelPos.push(x+1, y); }else if(!right && !matchColor(canvas, x+1, y, startR, startG, startB, startA)) { right = true; } drawFill(canvas, x, y); y++; if(y >= canvasHeight || !matchColor(canvas, x, y, startR, startG, startB, startA)) { bottom = true; // 移除错误的额外drawFill调用 } } } } //----- Check Color Match Function -----\\ function matchColor(canvas, x, y, startR, startG, startB, startA) { var tempPos = canvas.getImageData(x, y, 1, 1).data; var tempR = tempPos[0], tempG = tempPos[1], tempB = tempPos[2], tempA = tempPos[3]; return tempR == startR && tempG == startG && tempB == startB && tempA == startA; } //----- Hexadecimal to RGB Function -----\\ 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) } : null; } //================================\\
内容的提问来源于stack exchange,提问作者BusinessName123
相关产品推荐
相关产品推荐

