2010-11-11 13 views
5

Potrzebuję przetworzyć piksele z obrazu 1000x1000px * .bmp (~ 1MB) w javascript
W tej chwili jestem nieco zablokowany, ponieważ strona zawiesza się, gdy próbuję zrzucić dane do konsoli .
ważny kod do tej pory:pobierz piksel z bitmapy

var img = new Image(); 
img.src = 'image.bmp'; 
context.drawImage(img, 0, 0); 
console.log(context.getImageData(0, 0, canvas.height, canvas.width); 

myślę, że jest to problem z wydajnością, ale czy jest lepszy sposób, aby uzyskać dostęp do danych pikseli? Naprawdę nie muszę czytać wszystkiego naraz, czytanie pikseli po kolei byłoby również w porządku.

EDIT:

tutaj jest zaktualizowany kod, to wypełnić 2D tablicę z czerwonym wartości obrazu (mam do czynienia z czarnym/białym obrazie, więc to wystarczy)

var img = new Image(); 
img.src = 'image.bmp'; 
context.drawImage(img, 0, 0); 
var imgData = context.getImageData(0, 0, canvas.height, canvas.width); 
var pixel = new Array(); 
for(i=0;i<canvas.height;i++){ 
    pixel[i] = new Array(); 
    for(j=0;j<canvas.width;j++){ 
     pixel[i][j] = imgData.data[i*canvas.width+j*4]; 
    } 
} 
//now pixel[y][x] contains the red-value of the pixel at xy in img 

żadne problemy z wydajnością :) tylko dziwactwo jest to, że wiersze/kolumny są odwrócone

+2

Głupie pytanie: Czy próbowałeś zrobić to najpierw z małym obrazkiem, żeby to zadziałało? – epascarello

+4

Czy wysyłasz * 1 milion pikseli * do konsoli i zastanawiasz się, dlaczego przeglądarka zawiesza się? Poważnie? –

+1

Pekka: Tak, doszedłem do wniosku, że to był problem z wydajnością, gdybym wiedział, jak uzyskać dostęp do pikseli jeden po drugim, nie zapytałbym. – fruight

Odpowiedz

4
var data = context.getImageData(0, 0, canvas.height, canvas.width); 
var count = 0; 
var tmr = null; 
var length = data.length; 
(pix = function() { 
    var r = data[count + 0]; 
    var g = data[count + 1]; 
    var b = data[count + 2]; 
    var a = data[count + 3]; 
    var rgba = 'rgba(' + r + ' ,' + g + ' ,' + b + ' ,' + a + ')'; 
    console.log(rgba); 
    if((count += 4) >= length) { 
     clearTimeout(tmr); 
     return; 
    } 
    tmr = setTimeout(pix, 1000/30); //at 30 fps 
})(); 
+0

Mam kilka pytań: w linii -1, czy nie powinno to być s/clr/tmr /? i co to jest (x = function() {})(); - struktura nazywana, więc mogę dowiedzieć się trochę więcej na ten temat (Google nie jest tak dobry z parens/nawiasami klamrowymi). Nie oznaczę tego jeszcze jako odpowiedzi, ponieważ nawet przy 300 fps zajmuje to prawie 1h. najpierw muszę przetestować drugą odpowiedź. – fruight

+0

również, Twój kod jest błędny: drukuje 4 bajty, ale tylko zwiększa 1 bajt, więc wyjścia nakładają się na 3 bajty, a ostatnie 3 wyjścia będą miały ostatnie wartości "niezdefiniowane", a jego data.data [...]. – fruight

+0

tak stary, to jest buggy przyznaję, że .. odpowiedziałem, kiedy jestem trochę śpiący :) Zaktualizowano mój post. Proszę spojrzeć na moją aktualizację. miłego dnia! –

0

Spróbuj utworzyć płótnie 1px 1px X, przesunąć obraz, a następnie odczytać imageData