2012-12-17 63 views
4

我正在進入2D/3D圖形項目,並且遇到性能問題。在畫布中迭代像素並將其中一些複製到另一個像素中的最快方法

我的算法需要兩個圖像:圖片和相對灰度深度圖。 我也有一個10畫布(「圖層」)初始空白的數組。注意:所有圖像具有相同的尺寸。

我需要檢查深度圖的每個像素X; Y,並根據其顏色值訪問10個畫布中的一個,並在其上繪製原始圖像的X,Y像素。

得到的算法是一樣成才:

for (var y = 0; y < totalHeight; ++y) { 
    for (var x = 0; x < totalWidth; ++x) { 
    var index = (y * totalWidth + x) * 4; // index of the current pixel 
    // parse depth level using luminosity method 
    var depthLevel = Math.round(
     0.21 * depthData[index] + 
     0.71 * depthData[index + 1] + 
     0.07 * depthData[index + 2] 
    ); 

    // get the proper layer to modify 
    var layerIndex = Math.floor((layersCount/256) * depthLevel); 
    var layerContext = layers[layerIndex].getContext("2d"); 
    var layerData = layerContext.getImageData(0, 0, totalWidth, totalHeight); 

    layerData.data[index] = originalData[index]; 
    layerData.data[index + 1] = originalData[index + 1]; 
    layerData.data[index + 2] = originalData[index + 2]; 
    layerData.data[index + 3] = originalData[index + 3]; 

    layerContext.putImageData(layerData, 0, 0); 
} 

這樣的一個循環大約需要3分鐘完成一個200x200的圖像!我很確定這個緩慢是由最後一個函數putImageData引起的。有沒有更快的方式來按照我需要的方式繪製像素?謝謝

回答

10

不要在循環的每次迭代中設置圖像數據。這是一個沉重的操作,你正在執行它40.000(200*200)次。
這應該爲你節省位處理能力:

var contexts = []; 
var data = []; 
// Save your contexts and data to 2 arrays. 
for (var i = 0; i < layers.length; i++) { 
    contexts[i] = layers[i].getContext("2d"); 
    data[i] = contexts[i].getImageData(0, 0, totalWidth, totalHeight); 
} 

for (var y = 0; y < totalHeight; ++y) { 
    for (var x = 0; x < totalWidth; ++x) { 
     var index = (y * totalWidth + x) * 4; // index of the current pixel 
     // parse depth level using luminosity method 
     var depthLevel = Math.round(
      0.21 * depthData[index] 
      + 0.71 * depthData[index + 1] 
      + 0.07 * depthData[index + 2]); 

     // get the proper layer to modify 
     var layerIndex = Math.floor((layersCount/256) * depthLevel); 

     data[layerIndex].data[index] = originalData[index]; 
     data[layerIndex].data[index + 1] = originalData[index + 1]; 
     data[layerIndex].data[index + 2] = originalData[index + 2]; 
     data[layerIndex].data[index + 3] = originalData[index + 3]; 
    } 
} 

// Apply your new data to the contexts. 
for (var i = 0; i < layers.length; i++) { 
    contexts[i].putImageData(data[i]); 
} 

我沒有測試過,但是這應該給你一點如何做到這一點的想法。

+2

你有沒有「救世主」徽章? :)非常感謝你,現在它的速度很快 – TheUnexpected

+0

哈哈,沒問題:D 徽章與否,接受的答案是足夠的回報^ _ ^ – Cerbrus

相關問題