javascript - llamar - lista de atributos html
¿Por qué los valores de CanvasPixelArray de HTML5 son ridículamente lentos y cómo puedo hacerlo más rápido? (4)
Curiosamente, los bucles a través de las matrices de objetos 2d son más rápidos que los calcos de desplazamiento de una matriz de 1d y no hay objetos. Formatee en consecuencia y vea si eso ayuda (en mis pruebas, fue 20 veces más rápido).
(cara a cara: este script podría bloquear tu navegador. Si lo ejecutas, siéntate por unos minutos y deja que haga lo suyo) 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;
}
Más información: http://discourse.wicg.io/t/why-a-straight-array-for-canvas-getimagedata/1020/6 - http://discourse.wicg.io/t/why-a-straight-array-for-canvas-getimagedata/1020/6 / http://discourse.wicg.io/t/why-a-straight-array-for-canvas-getimagedata/1020/6
Estoy tratando de hacer algunos efectos visuales dinámicos usando la manipulación de píxeles del lienzo HTML 5, pero me estoy encontrando con un problema donde el ajuste de píxeles en CanvasPixelArray es ridículamente lento.
Por ejemplo, si tengo un código como:
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);
El perfil con Chrome revela que se ejecuta un 44% más lento que el siguiente código donde CanvasPixelArray no se utiliza.
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);
Supongo que el motivo de esta ralentización se debe a la conversión entre los dobles de Javascript y los enteros de 8 bits sin signo, utilizados por CanvasPixelArray.
- ¿Es esta suposición correcta?
- ¿Hay alguna forma de reducir el tiempo dedicado a establecer valores en CanvasPixelArray?
Intente almacenar en caché una referencia a la matriz de píxeles de data
. Su ralentización podría atribuirse a los accesos de propiedad adicionales a imageData.data
. Vea este artículo para más explicación.
Ej. Esto debería ser más rápido que lo que tienes actualmente.
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);
No sé si esto te ayuda porque quieres manipular píxeles, pero para mí, en Firefox 3.6.8, solo la llamada a putImageData fue muy, muy lenta, sin realizar ninguna manipulación de píxeles. En mi caso, solo quería restaurar una versión anterior de la imagen que se había guardado con getImageData. Demasiado lento.
En cambio, lo tengo que funcionar bien usando toDataUrl / drawImage en su lugar. Para mí, funciona lo suficientemente rápido como para llamarlo al manejar un evento mousemove:
Ahorrar:
savedImage = new Image()
savedImage.src = canvas.toDataURL("image/png")
El para restaurar:
ctx = canvas.getContext(''2d'')
ctx.drawImage(savedImage,0,0)
Parece que estás haciendo una especie de "blitting", así que quizás drawImage o drawImage todo en putImageData podrían ayudar. Hacer bucles un cuarto de millón de veces para copiar píxeles individualmente, en lugar de utilizar operaciones masivas de "blitting", tiende a ser mucho más lento, y no solo en Javascript ;-).