2011-04-12 23 views
8

在我的應用程序中,我有一個處理Canvas ImageData的函數。它看起來是這樣的:在JavaScript中複製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, {...}); 

這當然會導致相同的imageDatas。

所以我的第二個想法是編輯processsData函數,所以它以某種方式操縱imageData的副本,而不是傳遞的imageData。我所有嘗試這樣做的嘗試都失敗了,或者效率非常低下。只是想知道是否有一種特殊的方式來做到這一點。提前致謝。

+0

您是否曾嘗試在將它傳遞給函數之前自行創建它的副本? – Pointy 2011-04-12 22:36:27

+0

我在哪裏製作副本並不重要,但我只想找出一種方法來製作一個,很容易。 – 2011-04-12 22:37:20

+0

這個「圖像數據」 - 這是你從畫布上回來的,對吧?如果是這樣,它只是一個數組...(*編輯*主要是一個數組) – Pointy 2011-04-12 22:44:22

回答

25

按照latest specificationImageData對象data屬性被初始化爲Uint8ClampedArray對象(而不是先前使用CanvasPixelArray對象),因此內ImageData數據可以與set方法容易地複製:

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

太棒了!謝謝。 – 2012-09-02 02:51:10

1

我想你應該能夠很容易地創建一個副本:(。第一個參數是圖形上下文)

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()」作品‘數據’陣列上 - 我THI但它總是很好,以確保。

3

只是想我會爲此線程再添加一個解決方案,並附帶指向我找到解決方案的重複線程的鏈接。我在這裏重新發布它,因爲在我的情況下它提供了一個優勢。

他們提出簡單地用

var dataCopy = new Uint8ClampedArray(imageData.data); 

克隆的ImageData對象的數據以後,如果要將此數據還原到您使用

imageData.data.set(dataCopy); 
的ImageObject

的imageData可能是從原始實例您克隆數據或新的ImageData對象。

在我的情況下,這種方法更好,因爲我正在處理一個WorkerThread內的ImageData對象。 WorekerThreads不允許訪問畫布對象或其上下文,因爲據我所知,這裏的技術不會幫助我。該解決方案;然而,伎倆。謝謝大家。

Duplicate Thread Offering Other Solutions.