业务背景:用户上传图案,从图案上进行着色,然后将颜色和相关信息传输到算法以进行图像着色,并最终生成生产所需的文档。
Profe Color take -end color take -up过程:
本文仅谈论过程1和3。
基本原理是在画布上绘制的(又称图像预处理,主要是作为像素数据解析),然后通过2D上下文getImagedata获得单像素的颜色。
但是,在我们的业务情况下,印刷图片的大小可能大于20000 * 20000 PX。面对大型颜色选择的场景,普通的预处理方法(直接在单个画布上)将导致画布崩溃,并且不能是校正颜色。
接下来说明各种方案的问题,优势和缺点。
请先输入Demo1。
该图片尺寸为14410×19938,将发现它将通过Getimagedata颜色取出。如果您在文档中绘制帆布(请勿使用屏幕范围),您会发现帆布被挂起来(您可以通过Demo2查看效果)
原因是浏览器将限制单个画布的大小。
由于单个画布受到限制,因此我自然会想到碎片。
一般原理是:将图像分为几块,每片绘制本地图像,以及颜色时,将坐标转换为相应的膜着色。
您可以参考此图片:
最重要的是构建以下数据结构,在着色时易于使用:
核心代码如下:
优势和缺点的优势:解决画布崩溃的问题。
缺点:处理大局时,主线程将阻塞几秒钟。
代码示例请参阅Demo3
尽管碎片可以解决问题,但在单击颜色(制作图像预处理)后,有一个明确的UI阻止现象:
因此,请尝试将时间耗尽的逻辑放在Web Works处理上。
经过性能分析后,发现绘图是最耗时的链接,因此将绘图过程转移到Web工作人员中。可以看到界面效应明显改进:
在使用Web Worker的过程中,我遇到了一些问题:
问题1:如果您无法访问工人中的DOM,则可以通过Image URL => blob => imageBitMap => drawMimage(imagebitmap)解决它。
问题2:工人受到同源的限制。底层是建立的,将生成G.alicdn.com的资源。与此域名不同,由于同源策略,浏览器将无法启用工人。
绕过的一种方式是一条字符串,但是经验的写作还不是很好,也无法使用TS。请参阅Ruan Yifeng老师的文章中的一种巧妙的写作方式:
这样,您可以根据普通的打字稿编写它。
但是,还有一些局限性,例如其中的一些高端用法,例如。
由于WebPack将通过Babel处理代码,因此某些方法将是正义的。上述创建工人的方法已通过,因此我们不会引入WebPack模块依赖关系,从而导致错误。
问题3:术后不支持回调原则。每次术后生成ID很简单。当工人通过后退时,如果发现找到相同的ID,则调用相应的回调。
主线程:
在工人中:
问题4:当道路的垃圾回收和切换时,我发现以前的记忆未恢复,因为工人没有释放。解决方案如下:
优势和缺点的优势:解决方案2的UI渲染问题,用户体验很好。
缺点:网络工作者具有一定的学习成本和成就成本;兼容性问题。
兼容的情况如下:
Web工作者兼容性是可以接受的,但是在屏幕外需要使用绘画工人,这令人担忧。
我们的业务场景很特别,可以限制用户浏览器,因此这不是问题。根据业务方案,需要考虑到适当的情况。
代码示例请参阅链接
以下是方案2和3图像预处理的性能差异,包括时间和内存。贝洛(Below)称为无工作和工人。
测试图片:7.1m,尺寸14410×19938。
时间计算方法:地段12次,删除最小值,留下10个测试值以获得平均值:
时间拉图片:1520毫秒
抽奖:3395毫秒
总时间:4915毫秒
记忆预处理之前
预处理后:内存不会上升和下降,GPU内存上升1.5g
时间拉图片:97毫秒
斑点:693毫秒
创建位图:1985 ms
抽奖:1536毫秒
总时间:4311 ms
注意:没有工人时,这里的图片与拉动图片不同。没有工人使用img.src,它将包含一个完整的像素数据。这只是提取,所以时间差距很大。
记忆预处理之前
预处理后:内存上升1.1g,GPU内存升高1.5G。
就时间而言,两者几乎相同。
但是,如果被拆除,可以发现它是绘画的。工人仅成本为1536毫秒,没有工人,它的价格为3359毫秒,是长度的2倍。
为什么这是尚未找到答案。
在记忆中,工人将占据更多内存。
原因是绘图画布数据存储在工人中。
为什么没有工人的记忆不增加和跌倒?也将探索这个问题。
1. JS解码图像
也就是说,直接在JS中解码图片,然后尝试此解码库。图片中稍大一点将导致浏览器崩溃。
2.压缩图片后,再次采用颜色
尝试用OSS压缩它,将有一个尺寸限制(4096 * 4096)。
您可以通信以压缩后端。
或可以在画布绘制过程中压缩图片,并在颜色时进行坐标转换,但缺乏通用性。
原始:https://juejin.cn/post/7098318817474363423