FabricJS v3.4.0:过滤器和 maxTextureSize - performance/size 限制

FabricJS v3.4.0: Filters & maxTextureSize - performance/size limitations

简介:

我一直在搞乱 fabricJS 图像过滤功能,试图在我的网络应用程序中开始使用它们,但我已经 运行 进入以下内容。

似乎 fabricJS 默认只将过滤器上的图像大小上限(textureSize)设置为 2048,这意味着最大图像为 2048x2048 像素。

我试图通过调用 fabric.isWebGLSupported() 然后设置 fabric.textureSize = fabric.maxTextureSize 来提高默认值,但它仍然限制在 4096x4096 像素,即使我设备上的 maxTextureSize 在 16000~范围。

我知道设备通常会报告完整值而不考虑当前实际可用的内存,但这似乎仍然是一个硬性限制。

所以我想我在这里看到的主要问题是开始有效地使用此功能:

1-渲染阻塞applyFilters()方法:

当前的滤镜应用程序功能似乎在浏览器中呈现阻塞,有没有一种方法可以在不阻塞呈现的情况下调用它,这样我就可以显示一个不确定的加载微调器或其他东西?

是不是就像使应用过滤器方法异步并从应用程序的其他地方调用它一样简单? (我在上下文中使用 vue,webpack/babel which polyfills async/await 等)

2- 大小限制:

有没有办法绕过图片的大小限制?我希望过滤最大 4800x7200 像素的图像

我至少能想到一种方法,那就是 "break up" 将图像分成较小的图像,应用滤镜,然后将它们拼接在一起。但我担心这可能会影响性能,因为在此过程中会有很多 canvas 导出和 canvas 初始化。

我很惊讶 fabricjs 默认情况下不这样做 "chunking" 因为它是一个非常全面的库,我认为他们已经到了使用 webGL 着色器的地步(这是一个黑色box to me)用于在引擎盖下过滤以提高性能,有没有更好的方法来做到这一点?

我的另一个解决方案是将图像发送到一项服务(一个我手卷,或一个预先存在的付费服务),该服务在云中的某个地方应用过滤器,然后 returns 将其发送给用户,但是那不是我现在更愿意求助的解决方案。

对于上下文,我主要使用 fabric.Canvasfabric.StaticCanvas 在我的应用程序中初始化 canvases。

如果 insights/help 有这个就好了。

我和 Scott Seaward 先生(也归功于他)一起为 fabricJS 编写了过滤后端,我可以给你一些答案。

硬块到 2048

许多仅集成英特尔显卡的 macbook 报告最大纹理大小为 4096,但随后它们使 webgl 实例崩溃,高于 2280。这种情况在 2017 年编写 webgl 过滤时广泛发生。默认情况下,4096 会留下很多笔记本。也不要忘记手机。 您知道您的用户群,您可以将限制限制在您的视频卡允许的范围内以及 canvas 在您的浏览器中允许的范围内。最终图像,纹理可以有多大,必须复制到 canvas 中并显示。 (canvas 具有不同的最大大小,具体取决于浏览器和设备)

渲染阻止 applyFilters() 方法

据我所知,Webgl 是同步的。 在线程中创建并行执行以过滤大约 20-30 毫秒(在 chrome 中有时只有几毫秒)的操作似乎过多。

还考虑到我尝试过,但是当在 firefox 中打开超过 4 个 webgl 上下文时,有些会被删除。所以我决定一次买一个。

非 webgl 过滤当然需要更长的时间,这可能在一个单独的线程中完成,但 fabricJS 是一个通用库,它可以同时执行向量和过滤以及序列化,它已经准备好了很多东西,过滤表演还不错。但我愿意围绕它争论。

分块

Shutterstock 编辑器使用 fabricJS,这是编写 webgl 后端的主要原因。该编辑器还具有分块功能,可以使用 2048 像素大图像的图块进行过滤。我们没有将其作为开源发布,我也不打算询问。这种平铺限制了您可以编写的过滤器类型,因为代码有时只能了解图像的有限部分,即使只是模糊也会变得复杂。

这里有平铺过程的描述,是写给随便reader的,不只是软件工程师,只是一个博客post。 https://tech.shutterstock.com/2019/04/30/canvas-webgl-filtering-concepts

一般渲染阻塞注意事项

所以 fabricJS 有一些用着色器制作的预写过滤器。 这里记下的时间是我记忆中的,没有经过验证

逝去滤镜时间为:

  • 正在GPU中上传图片(不知多少ms)
  • 编译着色器(最多 40 毫秒,视情况而定)
  • 运行着色器(大约 2 毫秒)
  • 在 GPU 上下载结果(例如 0 毫秒或 13 取决于使用的方法)

现在,您第一次 运行 对单个图像使用滤镜时:

  • 图片已上传
  • 过滤编译
  • 着色器运行
  • 下载结果

你第二次这样做:

  • 着色器运行
  • 下载结果

添加新过滤器或更改过滤器时:

  • 已编译新过滤器
  • 着色器或两者着色器运行
  • 下载结果

我注意到在使用过滤构建应用程序时最常见的错误是:

  • 您忘记删除旧滤镜,使它们处于活动状态,其值接近 0,不会产生视觉变化,但会增加时间
  • 您将过滤器连接到滑块更改事件,没有节流,这取决于 browser/device 每秒最多可进行 120 次过滤操作。

看官方的简单demo: http://fabricjs.com/image-filters

使用滑块过滤,应用更多过滤器,我觉得一切都很顺利。