css - 为什么CSS3滤镜效果比HTML5 Canvas等效效果更好?

标签 css html5 css3 html5-canvas css-filters

我目前正在玩应用简单的过滤效果到一个HTML5画布上的图像。与此处定义的技术类似:
HTML5 Canvas image contrast
在这个HTML5 Rocks! blog post
但是,这种特殊的方法需要迭代每个像素,并在重绘之前应用一个修饰符。对于我的特定用例,这需要150ms+来重绘我的图像(650px乘以650px PNG)
使用CSS3's filter property(对比度或亮度)应用相同的效果需要不到10毫秒。
我的问题是:CSS3的过滤属性是如何在“幕后”工作的?为什么它的性能显著提高?有没有办法在画布上实现类似的性能?

最佳答案

画布通过API公开。JavaScript是一个运行时,尽管这些天来已经进行了严格的优化,但是如果您要通过JavaScript逐像素访问来操作2D网格,那么您将为每个像素支付从运行时到包含当前存储在画布中的图像的缓冲区的访问罚款。这个问题与你用JavaScript来表达过滤代码的事实有关,即使是经过优化的,运行时的性质也规定了一些不能去掉的惩罚。
CSS3过滤器是一个黑盒,可以批量执行相同的转换,这意味着GPU着色程序(shader program)直接在GPU上运行,访问通常存储在靠近GPU的可直接寻址内存中的图像,后者benefiting from its SIMD-class instructions用于处理像素的整个矩阵。另外,本机代码访问本地内存的速度几乎和访问本地内存的速度一样快,而不涉及细节。
即使在CPU上运行时,没有任何GPU的帮助,我们谈论的是本机过滤内核直接在RAM中操作图像,没有任何字节码,更重要的是根本没有考虑JavaScript。你声明你想要的过滤器,用户代理调用画布图像上的过滤器程序,就这样。CPU也有SIMD指令来处理数据向量,这显然有很大帮助。过滤代码甚至不是您的,您只需按名称引用它。
现在,如果您可以直接对画布像素数据应用某种类似CSS中可用的黑盒过滤器,那么您可能会获得与CSS相同的速度,因为您拥有的最重要的速度障碍——用JavaScript代码表示的逐像素访问——已经消除。所以这不仅仅是关于JavaScript,而是关于数据访问的粒度。在这种情况下,将内核批量应用于数据总是比自己在更高级别上编写内核代码要快。简单地说,这就引出了下面最后一点。
现在,如果JavaScript解释器能够理解你的逐像素循环操作,从某种意义上说,它可以将其全部转换为使用SIMD的本机代码,甚至可能是GPU shaders,所有这些都来自你自由键入的JavaScript过滤代码,那将缩小性能差距。但是,你会把复杂度转移到JavaScript编译器/解释器中,这样的规模优化问题在计算机科学中还不是一个完全解决的问题。也许人工智能和机器学习会有帮助,我不这么认为。请注意,我并不是说将JavaScript转换为等价的本地代码,这已经是多年来的惯例了,我是说将自由输入的JavaScript代码识别为类似于已知的甚至是任意的图像内核的代码,这与人类的做法很相似。然后将所述代码替换为一个运行时对应的代码,该代码给出相同的结果,但由编译器编写,以产生其认为将提供最佳性能的结果。
在实践中,如果深入研究JIT-compiling,我认为您可以逐个像素地优化基于画布的JavaScript纯像素过滤器。图像数据可以通过Uint8ClampedArray类型访问,您可以从CanvasRenderingContext2D.getImageData()方法调用获取该类型。这种数组类型有一些有趣的“大容量”函数,如filterforEachmapreduce等。在浏览Canvas API文档时,您需要像“黑客”一样思考,以假设一个Canvas API人的心态——根据他们能给您的东西来查看可用的方法和数据类型。这样做的回报是巨大的。
如果这还不够,可以使用demoscene呈现画布,这是WebGL的一个子集API,通常实现为仅在GPU上运行。着色器被保证是WebGL的一部分,这意味着您可以免费使用WebGL的各种高级和超高速画布过滤程序,这些程序是您自己编写的,但通常在GPU上执行。

关于css - 为什么CSS3滤镜效果比HTML5 Canvas等效效果更好?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43822886/

相关文章:

html - 如果它在容器中,则将 div 设为 100%

css - 如何将这些 div 水平放置在一行中,并带有水平滚动条

javascript - 为div链接制作nofollow行为

html - 图像 slider 过度滚动

html - 为什么动画在悬停时暂停在IE中起作用,但在Chrome或Edge中不能起作用?

javascript - 从另一个按钮触发分配给某个类的操作

html - 是否有用于将 Flash/Flex AS3 TextLayoutFormat 数据转换为 HTML 和 CSS 的库?

html - html/css是否可以使用此布局?

css3 - CSS3渐变自定义背景

css - 渐变IE8 +所需的最低CSS