【发布时间】:2015-03-10 02:20:41
【问题描述】:
此图像加载到 html5 画布中。
如果用户在正方形内的任何点按下,我想用颜色填充这个区域。但就在里面,颜色停在黑线处。您可以考虑像 Windows Paint 中的填充工具。
我该如何解决这个问题?是否有用于此类功能的 javascript 库?
【问题讨论】:
标签: javascript html design-patterns canvas image-recognition
此图像加载到 html5 画布中。
如果用户在正方形内的任何点按下,我想用颜色填充这个区域。但就在里面,颜色停在黑线处。您可以考虑像 Windows Paint 中的填充工具。
我该如何解决这个问题?是否有用于此类功能的 javascript 库?
【问题讨论】:
标签: javascript html design-patterns canvas image-recognition
您要查找的内容称为flood fill algorithm。这基本上会将您单击的像素的颜色作为种子。它将检查连接到种子像素且具有与种子相同颜色的所有像素,并将它们填充为所需的颜色。该算法有两种类型:8 向和 4 向。邻居是这样定义的(S = Seed, X = Connected):
四向
----------------
| | X | |
----------------
| X | S | X |
----------------
| | X | |
----------------
8向
----------------
| X | X | X |
----------------
| X | S | X |
----------------
| X | X | X |
----------------
递归算法是这样的(来自维基百科):
Flood-fill (node, target-color, replacement-color):
1. If target-color is equal to replacement-color, return.
2. If the color of node is not equal to target-color, return.
3. Set the color of node to replacement-color.
4. Perform Flood-fill (one step to the west of node, target-color, replacement-color).
Perform Flood-fill (one step to the east of node, target-color, replacement-color).
Perform Flood-fill (one step to the north of node, target-color, replacement-color).
Perform Flood-fill (one step to the south of node, target-color, replacement-color).
5. Return.
【讨论】:
您可能想使用CanvasRenderingContext2D.isPointInPath()
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
ctx.clicked = false;
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.save();
ctx.rotate(45);
ctx.beginPath();
ctx.rect(100, -100, 100, 100);
if (ctx.clicked) {
ctx.fillStyle = "blue";
ctx.fill()
}
ctx.stroke();
ctx.restore();
}
draw();
canvas.addEventListener('click', function(e) {
var bounds= canvas.getBoundingClientRect();
var mouseXY = [e.clientX-bounds.left, e.clientY-bounds.top]
ctx.clicked = ctx.isPointInPath(mouseXY[0], mouseXY[1]);
draw();
});
canvas {
border: 1px solid
}
<canvas id="canvas" height="500" width="500"></canvas>
【讨论】: