Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/86.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么CSS3过滤效果比HTML5画布效果更出色?_Html_Css_Html5 Canvas_Css Filters - Fatal编程技术网

为什么CSS3过滤效果比HTML5画布效果更出色?

为什么CSS3过滤效果比HTML5画布效果更出色?,html,css,html5-canvas,css-filters,Html,Css,Html5 Canvas,Css Filters,我目前正在尝试将简单的过滤效果应用到HTML5画布上的图像。与此处定义的技术类似: 在这个 然而,这种特殊的方法需要迭代每个像素,并在重画之前应用修改器。对于我的特定用例,这需要150ms+来重新绘制我的图像(650px乘以650px PNG) 使用(对比度或亮度)应用相同效果所需时间少于10毫秒 我的问题是:CSS3的过滤器属性“在引擎盖下”是如何工作的?为什么它的性能会显著提高?有没有办法在Canvas中实现类似的性能?Canvas是通过API公开的。JavaScript是一个运行时,即使

我目前正在尝试将简单的过滤效果应用到HTML5画布上的图像。与此处定义的技术类似:

在这个

然而,这种特殊的方法需要迭代每个像素,并在重画之前应用修改器。对于我的特定用例,这需要150ms+来重新绘制我的图像(650px乘以650px PNG)

使用(对比度或亮度)应用相同效果所需时间少于10毫秒


我的问题是:CSS3的过滤器属性“在引擎盖下”是如何工作的?为什么它的性能会显著提高?有没有办法在Canvas中实现类似的性能?

Canvas是通过API公开的。JavaScript是一个运行时,即使这些天进行了严格的优化,如果您打算使用JavaScript逐像素访问操作2D网格,您将为每个像素支付从运行时到包含当前存储在画布中的图像的缓冲区的访问的罚款。问题在于,您使用JavaScript表达过滤代码,即使经过优化,运行时的性质决定了一些无法消除的惩罚

CSS3过滤器是一个黑匣子,可以批量执行相同的转换,这意味着着色器程序直接在GPU上运行,访问通常存储在靠近GPU的可立即寻址内存中的图像,后者用于处理整个像素矩阵。此外,本机代码访问本地内存的速度非常快,无需详细说明

即使在CPU上运行时,没有任何GPU的帮助,我们也在谈论本机过滤器内核直接在RAM中操作图像,没有任何字节码,更重要的是根本没有考虑JavaScript。声明所需的过滤器,用户代理调用画布图像上的过滤器程序,就是这样。CPU还具有处理数据向量的SIMD指令,这显然有很大帮助。过滤代码甚至不是您的,您只按名称引用它

现在,如果您可以将某种黑盒过滤器(如CSS中可用的黑盒过滤器之一)直接应用于画布像素数据,您可能会获得与CSS相同的速度,因为速度的最重要障碍——用JavaScript代码表示的逐像素访问——已经消除。所以这不仅仅是关于JavaScript,这是关于数据访问的粒度。在这种情况下,将内核应用于批量数据总是比自己在更高级别上编写内核代码更快。简单地说,这就引出了下面的最后一点

现在,如果JavaScript解释器能够理解您的逐像素循环操作,即它可以将所有操作转换为使用SIMD的本机代码,甚至可能全部转换为自由键入的JavaScript过滤器代码,这将弥补性能差距。但是,您可能会将复杂性转移到JavaScript编译器/解释器中,而在计算机科学中,如此大规模的优化问题还不是一个完全解决的问题。也许人工智能和机器学习会有所帮助,我不会对此进行推测。请注意,我并不是说你的JavaScript是等效的本机代码,这已经是多年来的标准,我是说,将自由类型的JavaScript代码识别为类似于已知的,甚至是任意图像内核的东西,就像人类一样。然后用运行时对应的代码替换所述代码,该运行时对应的代码给出相同的结果,但由编译器编写,以产生它认为将提供最佳性能的代码

在实践中,我认为如果您深入研究这个问题,您可以优化基于画布的JavaScript朴素逐像素过滤器。可以通过
uint8clampedaray
类型访问图像数据,您可以从
canvasrrenderingcontext2d.getImageData()
方法调用获取该类型。这种数组类型有一些有趣的“批量”函数,如
filter
forEach
map
reduce
等。在浏览Canvas API文档时,您需要像“黑客”一样思考,以一个人的心态来看待可用的方法和数据类型,看它们能为您提供什么。这样做的回报是巨大的


如果这还不够,可以使用API呈现画布,该API是的子集,通常实现为仅在GPU上运行。着色器保证是WebGL的一部分,这意味着您可以免费使用WebGL访问各种高级和超高速画布过滤器程序,这些程序是您自己编写的,但通常在GPU上执行。

我知道评论不是为了这个,但是。。。哇!对细节和解释感到惊讶。非常感谢您抽出时间!事实上,我在浏览的时候看到了你的问题,我对这个问题感兴趣真是太傻了,而且我有图形处理的背景,我觉得写一个答案是完全正确的。我很高兴你觉得它有用。当然还有更多的内容,但我已经开始担心这会是一堵太多的文字墙。请仔细看看API,f.e.at(请注意,半授权源代码,所以请记住这一点)。我可能真的想在以后的答案中添加更多内容来改进它。