在JavaScript中按值复制imageData

12 javascript html5 canvas reference

在我的应用程序中,我有一个处理Canvas ImageData的函数.它看起来像这样:

function processData(imagedata, filters) {
  var data = imagedata.data;
  //manipulate data with filters
  imageData.data = data;
  return imageData;
}
Run Code Online (Sandbox Code Playgroud)

我一直在用它:

var imageData = processData(imageData, {...});
Run Code Online (Sandbox Code Playgroud)

但是因为imageData对象是通过引用传递的,所以它也会像这样工作:

processData(imageData, {...}); // no assignment
Run Code Online (Sandbox Code Playgroud)

我已经在我的项目中找到了一个点,我需要能够处理一些imageData,同时仍然可以访问原始数据.我的第一次尝试类似于以下内容:

var originalData = imageData;
var processedData = processData(imageData, {...});
Run Code Online (Sandbox Code Playgroud)

这当然会导致相同的imageDatas.

所以我的第二个想法是编辑processsData函数,以便它以某种方式操纵imageData的副本,而不是传递的imageData.我尝试这样做的所有尝试都失败了,或者效率非常低.只是想知道是否有一种特殊的方法来做到这一点.提前致谢.

its*_*kov 27

根据最新的规范, ImageData对象data属性被初始化为一个Uint8ClampedArray对象(而不是之前使用过的CanvasPixelArray对象),因此ImageData可以使用set方法轻松复制其中的数据:

function copyImageData(ctx, src)
{
    var dst = ctx.createImageData(src.width, src.height);
    dst.data.set(src.data);
    return dst;
}
Run Code Online (Sandbox Code Playgroud)


Chr*_*ger 8

只是想我会向这个线程添加一个更多的解决方案,以及一个指向我找到解决方案的重复线程的链接。我在这里重新发布它,因为就我而言,它提供了一个优势。

他们建议简单地克隆 ImageData 对象的数据

var dataCopy = new Uint8ClampedArray(imageData.data);
Run Code Online (Sandbox Code Playgroud)

稍后,如果您想将此数据恢复到您使用的 ImageObject

imageData.data.set(dataCopy);
Run Code Online (Sandbox Code Playgroud)

imageData 可能是您从中克隆数据的原始实例或新的 ImageData 对象。

在我的情况下,这种方法更好,因为我在 WorkerThread 中使用 ImageData 对象。WorekerThreads 不允许访问画布对象或其上下文,所以据我所知,这里的技术对我没有帮助。这个解决方案;然而,成功了。谢谢大家。

提供其他解决方案的重复线程。