Frage

Ich versuche, einige dynamische visuelle Effekte zu tun, um die HTML 5 Canvas' Pixelmanipulation, aber ich bin mit in ein Problem, bei dem Pixel in der CanvasPixelArray Einstellung langsam lächerlich.

Zum Beispiel, wenn ich Code wie:

imageData = ctx.getImageData(0, 0, 500, 500);

for (var i = 0; i < imageData.length; i += 4){
    imageData.data[i] = buffer[i];
    imageData.data[i + 1] = buffer[i + 1];
    imageData.data[i + 2] = buffer[i + 2];
}

ctx.putImageData(imageData, 0, 0);

Profilerstellung mit Chrome zeigt, läuft es 44% langsamer als der folgende Code in dem CanvasPixelArray nicht verwendet wird.

tempArray = new Array(500 * 500 * 4);
imageData = ctx.getImageData(0, 0, 500, 500);

for (var i = 0; i < imageData.length; i += 4){
    tempArray[i] = buffer[i];
    tempArray[i + 1] = buffer[i + 1];
    tempArray[i + 2] = buffer[i + 2];
}

ctx.putImageData(imageData, 0, 0);

Meine Vermutung ist, dass der Grund für diese Verlangsamung der Umwandlung durch die CanvasPixelArray zwischen dem Javascript verdoppelt und der internen unsigned 8-Bit-Integer, verwendete fällig ist.

  1. Ist diese Vermutung richtig?
  2. Gibt es trotzdem, um die Zeit zu reduzieren Werte in der CanvasPixelArray verbrachte Einstellung?
War es hilfreich?

Lösung

Versuchen Sie, eine Referenz auf das Array data Pixel Caching. Ihre Verlangsamung könnte auf die zusätzliche Eigenschaft Zugriffe auf imageData.data zurückzuführen. Siehe diesen Artikel für weitere Erklärung.

z. Dies sollte schneller das, was Sie im Moment haben.

var imageData = ctx.getImageData(0, 0, 500, 500),
    data = imageData.data,
    len = data.length;

for (var i = 0; i < len; i += 4){
 data[i] = buffer[i];
 data[i + 1] = buffer[i + 1];
 data[i + 2] = buffer[i + 2];
}

ctx.putImageData(imageData, 0, 0);

Andere Tipps

Ich weiß nicht, ob dies hilft Ihnen, weil Sie Pixel manipulieren wollen, aber für mich, in Firefox 3.6.8, nur der Aufruf von putImageData war sehr, sehr langsam, ohne jede Pixelmanipulation zu tun. In meinem Fall, ich wollte nur eine frühere Version des Bildes wiederherzustellen, die mit getImageData gerettet worden waren. Zu langsam.

Stattdessen habe ich es gut zu arbeiten, anstatt toDataURL / drawImage verwenden. Für mich ist es schnell genug arbeiten, dass ich es im Umgang mit einem mousemove- Ereignis nennen kann:

speichern:

savedImage = new Image()  
savedImage.src = canvas.toDataURL("image/png")

Die wiederherzustellen:

ctx = canvas.getContext('2d')  
ctx.drawImage(savedImage,0,0)

Sieht aus wie Sie tun, eine Art „Blitten“, so vielleicht drawImage oder all-at-once putImageData könnte helfen. Pixel einzeln zu kopieren, anstatt massiven „Blitten“ -Operationen, tendenziell zu viel langsamer ein Viertel Millionen Mal Looping - und nicht nur in Javascript, -).

Oddly, Schleifen durch 2D-Objekt-Arrays sind schneller als ein 1D-Array Offset Calcs und keine Objekte. Format entsprechend an und sehen, ob das hilft (in meinen Tests war es 20x schneller).

(Heads-up: dieses Skript Ihrem Browser abstürzen könnte, wenn Sie es laufen, sitzen fest für ein paar Minuten und lassen Sie es nicht sein Ding) http://jsfiddle.net/hc52jx04/16/

function arrangeImageData (target) {

var imageCapture = target.context.getImageData(0, 0, target.width, target.height);
var imageData = {
    data: []
};
imageData.data[0] = [];
var x = 0;
var y = 0;
var imageLimit = imageCapture.data.length;

for (var index = 0; index < imageLimit; index += 4) {

    if (x == target.width) {
        y++;
        imageData.data[y] = [];
        x = 0;
    }

    imageData.data[y][x] = {
        red: imageCapture.data[index],
        green: imageCapture.data[index + 1],
        blue: imageCapture.data[index + 2],
        alpha: imageCapture.data[index + 3]
    };
    x++;
}
return imageData;

}


function codifyImageData (target, data) {

var imageData = data.data;

var index = 0;
var codedImage = target.context.createImageData(target.width, target.height);

for (var y = 0; y < target.height; y++) {

    for (var x = 0; x < target.width; x++) {

        codedImage.data[index] = imageData[y][x].red;
        index++;
        codedImage.data[index] = imageData[y][x].green;
        index++;
        codedImage.data[index] = imageData[y][x].blue;
        index++;
        codedImage.data[index] = imageData[y][x].alpha;
        index++;
    }

}

return codedImage;

}

Weitere Informationen: http: / /discourse.wicg.io/t/why-a-straight-array-for-canvas-getimagedata/1020/6

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top