2012-12-17 6 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); 
} 

그런 루프 200x200 크기의 이미지를 완성 약 3 분이 소요 :

생성 알고리즘 등가 someting이다! 느린 것은 마지막 함수 인 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

관련 문제