在 JavaScript 中按值复制 imageData

发布于 2024-11-01 01:58:19 字数 761 浏览 0 评论 0原文

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

function processData(imagedata, filters) {
  var data = imagedata.data;
  //manipulate data with filters
  imageData.data = data;
  return imageData;
}

我一直这样使用它:

var imageData = processData(imageData, {...});

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

processData(imageData, {...}); // no assignment

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

var originalData = imageData;
var processedData = processData(imageData, {...});

这当然会产生相同的图像数据。

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

In my application I have a function that processes Canvas ImageData. It looks something like this:

function processData(imagedata, filters) {
  var data = imagedata.data;
  //manipulate data with filters
  imageData.data = data;
  return imageData;
}

I have been using it like this:

var imageData = processData(imageData, {...});

But because the imageData object is passed by reference it will also work like this:

processData(imageData, {...}); // no assignment

I've come to a point in my project where I need to be able to process some imageData while still having access to the original data. My first attempt was similar to the following:

var originalData = imageData;
var processedData = processData(imageData, {...});

This of course would result in to identical imageDatas.

So my second thought was to edit the processsData function so it somehow manipulates a copy of the imageData, instead of the passed imageData. All my attempts to do this have failed or have been horribly inefficient. Just wondering if there is a special way to do this. Thanks in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

南风几经秋 2024-11-08 01:58:19

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

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

According to the latest specification ImageData object data attribute is initialized to a Uint8ClampedArray object (instead of earlier used CanvasPixelArray object), so data within ImageData could be easily copied with set method:

function copyImageData(ctx, src)
{
    var dst = ctx.createImageData(src.width, src.height);
    dst.data.set(src.data);
    return dst;
}
拧巴小姐 2024-11-08 01:58:19

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

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

var dataCopy = new Uint8ClampedArray(imageData.data);

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

imageData.data.set(dataCopy);

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

就我而言,此方法更好,因为我正在 WorkerThread 内处理 ImageData 对象。不允许 WorekerThreads 访问画布对象或其上下文,据我所知,这里的技术对我没有帮助。这个解决方案;然而,成功了。谢谢大家。

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

Just thought I would add one more solution to this thread along with a link to the duplicate thread on which I found the solution. I am re-posting it here because, in my case it offered an advantage.

They propose simply cloning the data of the ImageData object with

var dataCopy = new Uint8ClampedArray(imageData.data);

Later, if you want to restore this data to an ImageObject you use

imageData.data.set(dataCopy);

imageData may be the original instance from which you cloned the data or a new ImageData object.

In my case this method is better because I am working with ImageData objects inside of a WorkerThread. WorekerThreads are not allowed access to the canvas object or its context so as far as I can tell the techniques here would not help me. This solution; however, did the trick. Thanks All.

Duplicate Thread Offering Other Solutions.

夜空下最亮的亮点 2024-11-08 01:58:19

我认为你应该能够很容易地创建一个副本:(

function copyImageData(context, original) {
  var rv = context.createImageData(original.width, original.height);
  // would 
  //   rv.data = Array.prototype.slice.call(original.data, 0);
  // work?
  for (var i = 0; i < original.data.length; ++i)
    rv.data[i] = original.data[i];
  return rv;
}

第一个参数是图形上下文。)

然后你可以使用副本调用“processImageData”:

var newImage = processImageData(copyImageData(context, imageData));

编辑 - 我会尝试小提琴看看“.slice()”是否适用于“data”数组 - 我认为它会,但确定一下总是好的。

I think you should be able to create a copy pretty easily:

function copyImageData(context, original) {
  var rv = context.createImageData(original.width, original.height);
  // would 
  //   rv.data = Array.prototype.slice.call(original.data, 0);
  // work?
  for (var i = 0; i < original.data.length; ++i)
    rv.data[i] = original.data[i];
  return rv;
}

(The first argument is the graphics context.)

Then you can call "processImageData" with a copy:

var newImage = processImageData(copyImageData(context, imageData));

edit — I'll try a fiddle to see whether ".slice()" works on the "data" array - I think it will but it's always good to make sure.

放肆 2024-11-08 01:58:19

ImageData 构造函数 可用于克隆图像数据。

function cloneImageData(imgData) {
  return new ImageData(imgData.data, imgData.width, imgData.height)
}

The ImageData constructor can be used to clone image data.

function cloneImageData(imgData) {
  return new ImageData(imgData.data, imgData.width, imgData.height)
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文