Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/471.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
Javascript Web worker和缩放图像_Javascript_Html_Canvas - Fatal编程技术网

Javascript Web worker和缩放图像

Javascript Web worker和缩放图像,javascript,html,canvas,Javascript,Html,Canvas,我需要在Web Worker中以数组形式缩放图像。如果我在网络工作者之外,我可以使用画布和drawImage复制或缩放图像的某些部分 看起来像一个网络工作者,我不能使用画布,那么,我能做什么呢?有什么纯Javascript库可以帮助我吗 提前多谢。缩放可以通过各种方式完成,但它们都可以归结为从图像中删除或创建像素。由于图像本质上是像素值的矩阵(大小调整为数组),因此可以将放大图像视为放大该数组并填充空格,将缩小图像视为通过忽略值来缩小数组 也就是说,用JavaScript编写自己的可用于数组的s

我需要在Web Worker中以数组形式缩放图像。如果我在网络工作者之外,我可以使用画布和drawImage复制或缩放图像的某些部分

看起来像一个网络工作者,我不能使用画布,那么,我能做什么呢?有什么纯Javascript库可以帮助我吗


提前多谢。

缩放可以通过各种方式完成,但它们都可以归结为从图像中删除或创建像素。由于图像本质上是像素值的矩阵(大小调整为数组),因此可以将放大图像视为放大该数组并填充空格,将缩小图像视为通过忽略值来缩小数组

也就是说,用JavaScript编写自己的可用于数组的scale函数通常并不难。因为我知道您已经拥有JavaScript数组形式的图像,所以您可以将该数组以消息的形式传递给Web Worker,将其缩放为您的缩放函数,并将缩放后的数组发送回主线程

在表示方面,我建议您使用uint8clampedaray,它是为RGBA(颜色,带有alpha通道)编码图像设计的,比普通JavaScript数组更有效。您还可以轻松地将消息中的Uint8ClampedArray对象发送给Web工作人员,这样就不会有问题了。另一个好处是,在Canvas API的ImageData数据类型(替换CanvasPixelArray后)中使用UINT8ClampArray。这意味着,只需使用ctx.getImageData()获取画布2D上下文的当前ImageData并将其数据属性更改为缩放后的Uint8ClampedArray对象,就可以很容易地在画布上绘制缩放后的图像(如果您需要的话)

顺便说一下,如果您还没有将图像作为数组,那么您可以使用相同的方法。首先在画布上绘制图像,然后使用当前ImageData对象的data属性在Uint8ClampedArray中检索图像

关于放大图像的缩放方法,基本上需要实现两个组件。第一种方法是将已知像素(即缩放图像中的像素)分割到已创建的更大的新阵列上。一个明显的方法是在空间上均匀地划分所有像素。例如,如果要使图像的宽度增加一倍,只需跳过每个像素后的一个位置,在每个像素之间留下空白

第二个组成部分是填补这些空白,这可能会稍微不那么简单。然而,有几个是相当容易的。(另一方面,如果您对计算机视觉或图像处理有一定的了解,您可能希望了解一些更高级的方法。)一种简单而明显的方法是,通过复制已知像素的颜色,使用其最近邻点(即已知的最近像素值)对每个未知像素位置进行插值。当您过度缩放图像时,通常会产生较大像素(相同颜色的较大块)的效果。除了复制最近像素的颜色,还可以取附近几个已知像素的平均值。甚至可能与权重相结合,使距离较近的像素在平均值中比距离较远的像素计数更多。其他方法包括使用高斯模糊图像。如果您想找出最适合您的应用程序的方法,请查看有关图像插值的一些页面。当然,请记住,放大总是意味着填充实际上不存在的东西。如果你做得太多,这看起来总是很糟糕

就缩小而言,通常仅通过将选定的像素从当前阵列转移到较小的阵列来移除像素。例如,如果您希望使图像的大小加倍,则可以使用2的步骤大致迭代当前数组(这在一定程度上取决于图像的尺寸,偶数或奇数,以及所使用的表示)。有一些方法可以通过去除那些最容易丢失的像素来更好地做到这一点。但我对他们的了解还不够

顺便说一句,所有这些实际上都与网络工作者无关。如果您想在主线程上用JavaScript缩放图像,您可以完全按照同样的方式进行。或者用任何其他语言。然而,Web Workers是在单独的线程上而不是在UI线程上进行这些计算的一种非常好的方法,这意味着网站本身似乎没有响应。但是,正如您所说,所有涉及canvas元素的操作都需要在主线程上完成,但是扩展数组可以在任何地方完成

另外,我确信有一些JavaScript库可以为您实现这一点,并且根据它们的方法,您也可以使用importScripts将它们加载到Web Worker中。但我想说的是,在这种情况下,尝试自己编写并为自己的目的量身定做可能会更容易、更有趣

根据您的编程技能有多先进以及需要扩展的速度,您可以尝试在GPU上而不是在CPU上使用WebGL进行扩展。但在这种情况下,这似乎有点过头了。此外,您还可以尝试将图像分割成几块,并尝试在多个Web Workers上缩放单独的部分,使其成为多线程的。尽管以后再合并这些部分肯定不是件小事。当您有许多需要在客户端缩放的图像时,多线程可能更有意义

这一切都取决于你的应用程序、图像以及你自己的技能和愿望


无论如何,我希望这大致回答了您的问题。

我觉得需要对mslatour的答案进行详细说明,因为我刚刚花了6个小时试图找出如何“…简单地…将其数据属性更改为缩放的Uint8ClampedArray对象”。为此:

① s
self.postMessage(bufferToReturn, [bufferToReturn]);
self.postMessage({buffer:bufferToReturn, width:500, height:500}, [bufferToReturn]);
webWorker.addEventListener('message', function(event) {your code here})
var imageData = context2d.createImageData(width, height);
imageData.data.set(new Uint8ClampedArray(bufferToReturn));
context2d.putImageData(imageData, x_offset, y_offset);