javascript - 最小化 Canvas "bitmap"数据大小

标签 javascript algorithm node.js canvas base64

上下文:多用户应用程序 (node.js) - 1 个画家,n 个客户

Canvas 大小:650x400 像素(= 260,000 像素)

为了频繁更新 Canvas (我想每秒更新 10 次),我需要使数据大小尽可能小,尤其是在考虑上传速率时。

返回 base64 字符串的 toDataURL() 方法很好,但它包含大量我什至不需要的数据(每像素 23 位)。它的长度是 8,088(没有前面的 MIME 信息),假设 JavaScript 字符串有 8 位编码,这将是 8.1 KB 的数据,每秒 10 次。

我的下一次尝试是将 JS 对象用于不同的上下文操作,例如 moveTo(x, y)lineTo(x, y),将它们发送到服务器并让客户端接收增量更新中的数据(通过时间戳)。然而,事实证明这比 base64 字符串效率更低。

{ 
    "timestamp": 0, 
    "what": { 
       "name": LINE_TO, 
       "args": {"x": x, "y": y}  
    } 
}

它既不流畅也不精确,因为当您快速滑动画笔时,已经有将近 300 个 lineTo 命令。有时会缺少一部分运动(直线而不是圆形),有时脚本客户端甚至无法识别事件,因为它似乎被已经触发的大量事件“淹没”。

所以我最终不得不使用 base64 字符串及其 8.1 KB。我不想担心这么多——但即使通过增量更新异步完成,在真实服务器上也会有很大的滞后,更不用说偶尔的带宽超限了。

我使用的唯一颜色是#000 和#FFF,所以我考虑的是1 位数据结构 仅具有增量更新。这基本上就足够了,我不介意任何“颜色”精度损失(毕竟它是黑色)。

由于大部分 Canvas 都是白色的,您可以考虑使用额外的霍夫曼游程编码来进一步减小尺寸。就像大小为 50x2 像素且在 (26, 2) 处有一个黑色像素的 Canvas 将返回以下字符串:75W1B74W(50 + 25 个白色像素,然后是 1 个黑色像素,然后是 24 个以上的白色像素像素)

如果 Canvas 由这样的 1 位字符串组成,它甚至会有所帮助:

00000000000000000000000000000000000000000000000000 
00000000000000000000000001000000000000000000000000

那已经很有帮助了。

我的第一个问题是:如何编写算法来高效获取这些数据?

第二个是:我如何纯二进制 Canvas 数据传递给客户端(通过 Node 服务器)?我如何向服务器发送 1 位数据结构?我是否必须将我的位转换为十六进制(或更多)数字并重新解析?

是否可以使用 this作为数据结构?

提前致谢

哈蒂

最佳答案

I need to keep the data size as small as possible

然后不要发送整个数据。仅发送更改,接近您自己的建议。

使框架使每个用户只能执行“操作”,例如“从 X1,Y1 到 X2,Y2 绘制黑色 strokeWidth 2”。

我不会为一些纯二进制的东西而烦恼。如果只有两种颜色,那么很容易将其作为字符串“1,2,x,y,x2,y2”发送,其他人将以与本地客户端完全相同的方式解析它,并且将以相同的方式绘制.

我不会想太多。在您担心任何巧妙的编码之前,让它使用简单的字符串。值得先尝试简单的事情。也许不经历很多麻烦,性能会相当好!

关于javascript - 最小化 Canvas "bitmap"数据大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9569599/

相关文章:

java - 这个解决方案可以优化吗?

node.js - vuejs - 来自 chokidar 的错误(C :\): Error: EBUSY: resource busy or locked, lstat 'C:\hiberfil.sys'

javascript - Javascript 中的字符串转换(十进制到二进制)

javascript - 在多维数组中获取 Promise 的结果

algorithm - 查找数组中元素 >= k 的最大连续范围的次线性算法

javascript - 向后编写文本置乱算法

node.js - 如何通过 Node.js Bluemix 推送 API 注册设备

javascript - Node.js - 创建变量中指定类名的对象

javascript - 如何将自定义内容放入折叠的 ExtJS 面板栏中?

javascript - Controller 中的 AngularJS 过滤器 'startingAt'