我正在使用socket.io和canvas创建一个协作图像绘制应用程序根据需要,画布必须经常刷新,目前大约每50毫秒刷新一次。我想在应用程序中添加一个填充工具,所以我用我有限的洪水填充知识创建了一个。因为所有这些数据都必须传输,所以我将每个fill命令存储为一个简单的对象
{
tool: 'fill',
coordinate: {
x: 5,
y: 5
}
fillcolor: '#000'
}
然后,每个客户机的画布运行算法,并使用“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;
}
}
不幸的是,一旦算法运行画布绘制是荒谬的缓慢因为我所有的画都有鼠标坐标的细节,所以我考虑用矢量来填充,但是我的数学背景不足以在没有帮助的情况下完成。
我的申请有什么慢的地方我怎样才能修好它?
编辑:正如我在评论中提到的,我试过使用一个大的putImageData(非常慢),使用createImageData而不是getImageData(稍微快一些)。
EDIT2:每个画笔笔划都存储为一系列x-y坐标,当用户单击并拖动时会记录这些坐标然而,它们不是封闭的路径相反,它们被画成一系列的线,当用户抬起鼠标时,移动到的。
更新代码以反映我当前的实现。
最佳答案
我意识到这是一个很老的问题,但是如果你还在研究这个问题,请暂时在函数的各个部分输入一些计时代码,以找出它最慢的地方一定要把getimagedata和putimagedata的调用从循环中拉出来-每个“fill”只调用一次一旦获得了图像数据,就可以通过它的底层缓冲区(被看作uint32数组)获取并设置像素的颜色。
见
https://hacks.mozilla.org/2011/12/faster-canvas-pixel-manipulation-with-typed-arrays/