Foros del Web » Programando para Internet » Javascript »

putImageData no funciona con copia de ImageData

Estas en el tema de putImageData no funciona con copia de ImageData en el foro de Javascript en Foros del Web. Buenas, Tengo el siguiente código relacionado con el tema de pixelado del hilo de desafíos javascript 2014 : http://jsfiddle.net/jefebrondem/745Ds/4/ El problema es con el siguiente ...
  #1 (permalink)  
Antiguo 19/12/2013, 07:30
 
Fecha de Ingreso: julio-2006
Ubicación: Barcelona
Mensajes: 244
Antigüedad: 17 años, 9 meses
Puntos: 32
putImageData no funciona con copia de ImageData

Buenas,

Tengo el siguiente código relacionado con el tema de pixelado del hilo de desafíos javascript 2014:
http://jsfiddle.net/jefebrondem/745Ds/4/

El problema es con el siguiente código en particular:
Código Javascript:
Ver original
  1. btn.onclick=function(){
  2.         btn.setAttribute("disabled","disabled");
  3.         var imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
  4.         console.log( imageData.data[0] );
  5.         //setInterval( function(){
  6.             console.time( 'a' );
  7.             var copy = Object.create( imageData );
  8.             console.log( copy.data[0] );
  9.             var newImageData = pixelar(copy,canvas.width,canvas.height,pixeles);
  10.             console.timeEnd( 'a' );
  11.             console.log( newImageData.data[0] );
  12.             ctx.putImageData( newImageData, 0, 0);
  13.             console.log('eo');
  14.         //},1000 );
  15.         //console.log( imageData.data[0] );
  16.     }
Desearía conservar una copia del elemento imageData para poder pixelarlo de varias formas a partir del original. Para ello he creado una copia con la función Object.create y he pasado esta copia para pixelar. Todo funciona bien hasta que paso el resultado de la función pixelar al argumento de putImageData. He debugueado y no acabo de entender por qué, pues newImageData es también del tipo ImageData.

Un saludo y gracias!
__________________
github.com/xgbuils | npm/xgbuils
  #2 (permalink)  
Antiguo 19/12/2013, 10:35
Avatar de marlanga  
Fecha de Ingreso: enero-2011
Ubicación: Murcia
Mensajes: 1.024
Antigüedad: 13 años, 3 meses
Puntos: 206
Respuesta: putImageData no funciona con copia de ImageData

Object.create no sirve para clonar instancias, si no para copiar prototipo de objetos; y no funciona como parece que debe funcionar. Actúa sobre los prototipos, metiendo referencias. Es decir, si creas un objeto llamado B a partir de otro llamado A, en realidad estás copiando todas las referencias de las propiedades de A en el prototipo del objeto B. Pero si luego cambias por ejemplo, alguna propiedad de B, también se la estás cambiando a A.

De hecho, misteriosamente no hay ningún método para clonar instancias javascript de forma general.

En el caso concreto de lo que quieres hacer, tienes varias alternativas. Además de tener un canvas insertado en el DOM con su respectivo contexto, crear también otro contexto de un canvas virtual creado dinámicamente en memoria con createElement, pero sin meterlo nunca en el DOM. Pintas en ese contexto virtual, la imagen. Le sacas el ImageData, la procesas, y la dibujas en el contexto del canvas real que sí está en el DOM.
De hecho, hay una técnica llamada "doble buffer" implementada en canvas usando esta idea, en pintar en un contexto-canvas virtual, que es mucho mas rápido que pintar en el contexto-canvas visible insertado en el DOM. Cuando esté todo dibujado, se mete el contexto virtual en el contexto real con contextoReal.drawImage(contextoVirtual.canvas,0,0) .

También puedes dibujar la imagen otra vez antes de pixelarla, con drawImage,antes de hacer el getImageData de nuevo.

O hacer una copia del atributo DATA del CanvasImageData, y asignarle cuando quieras al CanvasImageData con el método set.
copia= new Uint8ClampedArray(imageData.data);
imageData.data.set(copia);

Última edición por marlanga; 19/12/2013 a las 10:43
  #3 (permalink)  
Antiguo 21/12/2013, 05:35
 
Fecha de Ingreso: julio-2006
Ubicación: Barcelona
Mensajes: 244
Antigüedad: 17 años, 9 meses
Puntos: 32
Respuesta: putImageData no funciona con copia de ImageData

No he tenido mucho tiempo estos días, pero al final he probado de crear un canvas virtual como dijiste. Y de ahí ir obteniendo la imagen original para modificando siempre con respecto a esa imagen.

Código Javascript:
Ver original
  1. var canvas  = document.getElementById("canvas");
  2.     var context = canvas.getContext( '2d' );
  3.     canvas.width  = img.width;
  4.     canvas.height = img.height;
  5.     context.drawImage(img, 0, 0, img.width, img.height);
  6.  
  7.     var original = document.createElement("canvas");
  8.     var originalContext = original.getContext( '2d' );
  9.     original.width  = img.width;
  10.     original.height = img.height;
  11.     originalContext.drawImage(img, 0, 0, img.width, img.height);
  12.    
  13.     var btn=document.getElementById('btn');
  14.     btn.onclick=function(){
  15.         btn.setAttribute("disabled","disabled");
  16.  
  17.         setInterval( function(){
  18.             imageData = originalContext.getImageData(0, 0, original.width, original.height);
  19.             context.putImageData( pixelar(imageData,img.width,img.height,pixeles), 0, 0);
  20.         },100 );
  21.     }

A primera vista parece que no tenga sentido lo que he hecho, pues parece que siempre se va a mostrar lo mismo. Pero lo que ocurre es que la función pixelar no goza de transparencia referencial. Pues, pixelar ahora toma una porción aleatoria de píxeles y de ahí hace la media. Aquí el código entero:
http://jsfiddle.net/jefebrondem/745Ds/5/

Gracias!
__________________
github.com/xgbuils | npm/xgbuils

Etiquetas: copia, funcion, html, js
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 20:19.