gpt4 book ai didi

javascript - 使 HTML5 canvas floodfill 高效

转载 作者:塔克拉玛干 更新时间:2023-11-03 06:02:04 24 4
gpt4 key购买 nike

我正在使用 socket.io 和 canvas 创建协作图像绘制应用程序。 Canvas 必须经常刷新,目前大约每 50 毫秒刷新一次。我想在应用程序中添加一个填充工具,所以我用我有限的 flood-fill 知识创建了一个。因为所有这些数据都必须传输,所以我将每个填充命令存储为一个简单的对象

{
tool: 'fill',
coordinate: {
x: 5,
y: 5
}
fillcolor: '#000'
}

然后每个客户端的 Canvas 运行算法并使用“getImageData”和“putImageData”填充每个单独的像素。这是我的实现的(简化)版本。

function floodfill (start,target_color,fill_color)
{
var pixelStack = [start]; //the stack of pixels to check

while (pixelStack.length > 0)
{
var current = pixelStack[pixelStack.length-1]; //check the last pixel of the pixelstack
pixelStack.pop(); //delete current from stack

if (isSameColor(current)) //matches our target color
{
var mydat = ctx.createImageData(1,1);
mydat.data = new Array();
mydat.data[0] = hexToRGB(fill_color).r; //red
mydat.data[1] = hexToRGB(fill_color).g; //green
mydat.data[2] = hexToRGB(fill_color).b; //blue
mydat.data[3] = 255;
ctx.putImageData(mydat,current.x,current.y);

pixelStack.push(bit(current.x+1,current.y)); //right
pixelStack.push(bit(current.x-1,current.y)); //left
pixelStack.push(bit(current.x,current.y+1)); //up
pixelStack.push(bit(current.x,current.y-1)); //down
}
}

function isSameColor (pixel)
{
var imgdat = ctx.getImageData(pixel.x,pixel.y,1,1).data;
if (imgdat[0]== hexToRGB(target_color).r && imgdat[1]== hexToRGB(target_color).g, imgdat[2]== hexToRGB(target_color).b)
{
return true;
}
else
{
return false;
}
}
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),
rgb: parseInt(result[1], 16) + ", " + parseInt(result[2], 16) + ", " + parseInt(result[3], 16)
} : null;
}
}

不幸的是,一旦运行了算法,canvas 绘图就会慢得离谱。由于我有所有绘画的鼠标坐标细节,我考虑尝试使用矢量来填充它,但我的数学背景还不够强大,无法在没有帮助的情况下完成。

我的应用程序的缓慢部分是什么?我该如何解决?

编辑:正如我在评论中提到的,我已经尝试过只使用一个大的 putImageData(非常慢),并使用 createImageData 而不是 getImageData(稍快一些)。

EDIT2:每个画笔笔触都存储为一系列 x-y 坐标,当用户单击和拖动时会记录这些坐标。但是,它们不是封闭路径。相反,它们被绘制为一系列线条,当用户抬起鼠标时,移动到。

代码已更新以反射(reflect)我当前的实现。

最佳答案

我知道这是一个非常古老的问题,但如果您仍在研究这个问题,请暂时放入一些代码来为函数的各个部分计时,以找出最慢的地方。绝对将对 getimagedata 和 putimagedata 的调用拉出循环——每次“填充”只调用一次。获得图像数据后,通过它的底层缓冲区获取和设置像素的颜色,将其视为 Uint32Array。

https://hacks.mozilla.org/2011/12/faster-canvas-pixel-manipulation-with-typed-arrays/

关于javascript - 使 HTML5 canvas floodfill 高效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17328870/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com