domingo, 28 de febrero de 2016

Procesando imágenes con API CANVAS



API Canvas no sería nada sin la capacidad de procesar imágenes. Pero incluso cuando las imágenes son un elemento tan importante para una aplicación gráfica, solo un método nativo fue provisto para trabajar con ellas.

drawImage()

El método drawImage() es el único a cargo de dibujar una imagen en el lienzo. Sin embargo, este método puede recibir un número de valores que producen diferentes resultados. Estudiemos estas posibilidades:

drawImage(imágen, x, y) :Esta sintaxis es para dibujar una imagen en el lienzo en la posición declarada por x e y. El primer valor es una referencia a la imagen que será dibujada.
drawImage(imágen, x, y, ancho, alto) :Esta sintaxis nos permite escalar la imagen antes de dibujarla en el lienzo, cambiando su tamaño con los valores de los atributos ancho y alto. 
drawImage(imágen, x1, y1, ancho1, alto1, x2, y2, ancho2, alto2) :Esta es la sintaxis más compleja. Hay dos valores para cada parámetro. El propósito es cortar partes de la imagen y luego dibujarlas en el lienzo con un tamaño y una posición específica. Los valores x1 e y1 declaran la esquina superior izquierda de la parte de la imagen que será cortada. Los valores ancho1 y alto1 indican el tamaño de esta pieza. El resto de los valores (x2, y2, ancho2 y alto2) declaran el lugar donde la pieza será dibujada en el lienzo y su nuevo tamaño (el cual puede ser igual o diferente al original).

En cada caso, el primer atributo puede ser una referencia a una imagen en el mismo documento generada por métodos como getElementById(), o creando un nuevo objeto imagen usando métodos regulares de Javascript. No es posible usar una URL o cargar un archivo desde una fuente externa directamente con este método.

Código 7-22. Trabajando con imágenes.

function iniciar(){
var elemento=document.getElementById('lienzo');
lienzo=elemento.getContext('2d');
var imagen=new Image();
imagen.src="http://www.minkbooks.com/content/snow.jpg";
imagen.addEventListener("load", function(){
lienzo.drawImage(imagen,20,20)
}, false);
}
window.addEventListener("load", iniciar, false);

Comencemos con un simple ejemplo. El código 7-22 lo único que hace es cargar la imagen y dibujarla en el lienzo. Debido a que el lienzo solo puede dibujar imágenes que ya están completamente cargadas, necesitamos controlar esta situación escuchando al evento load. Agregamos una escucha para este evento y declaramos una función anónima para responder al mismo. El método drawImage() dentro de esta función dibujará la imagen cuando fue completamente cargada. 
Conceptos básicos: En el Código 7-22, dentro del método addEventListener(), usamos una función anónima en lugar de una referencia a una función normal. En casos como éste, cuando la función es pequeña, esta técnica vuelve al código más simple y fácil de entender.  

Código 7-23. Ajustando la imagen al tamaño del lienzo.

function iniciar(){
var elemento=document.getElementById('lienzo');
lienzo=elemento.getContext('2d');
var imagen=new Image();
imagen.src="http://www.minkbooks.com/content/snow.jpg";
imagen.addEventListener("load", function(){
lienzo.drawImage(imagen,0,0,elemento.width,elemento.height)
}, false);
}
window.addEventListener("load", iniciar, false);

En el Código 7-23, agregamos dos valores al método drawImage() utilizado previamente para cambiar el tamaño de la imagen. Las propiedades width y height retornan las medidas del lienzo, por lo que la imagen será estirada por este código hasta cubrir el lienzo por completo.

Código 7-24. Extrayendo, cambiando el tamaño y dibujando.

function iniciar(){
var elemento=document.getElementById('lienzo');
lienzo=elemento.getContext('2d');
var imagen=new Image();
imagen.src="http://www.minkbooks.com/content/snow.jpg";
imagen.addEventListener("load", function(){
lienzo.drawImage(imagen,135,30,50,50,0,0,200,200)
}, false);
}
window.addEventListener("load", iniciar, false);

En el Código 7-24 el código presenta la sintaxis más compleja del método drawImage(). 
Nueve valores fueron provistos para obtener una parte de la imagen original, cambiar su tamaño y luego dibujarla en el lienzo. Tomamos un cuadrado de la imagen original desde la posición 135,50, con un tamaño de 50,50 pixeles. Este bloque es redimensionado a 200,200 pixeles y finalmente dibujado en el lienzo en la posición 0,0.


Datos de imágenes

Cuando dijimos previamente que drawImage() era el único método disponible para dibujar imágenes en el lienzo, mentimos. Existen unos poderosos métodos para procesar imágenes en esta API que además pueden dibujarlas en el lienzo. Debido a que estos métodos no trabajan con imágenes sino con datos, nuestra declaración previa sigue siendo legítima. ¿Pero por qué desearíamos procesar datos en lugar de imágenes? 
Toda imagen puede ser representada por una sucesión de números enteros representando valores rgba (cuatro valores para cada pixel). Un grupo de valores con esta información resultará en un array unidimensional que puede ser usado luego para generar una imagen. La API Canvas ofrece tres métodos para manipular datos y procesar imágenes de este modo:

getImageData(x, y, ancho, alto) :Este método toma un rectángulo del lienzo del tamaño declarado por sus atributos y lo convierte en datos. Retorna un objeto que puede ser luego accedido por sus propiedades width, height y data.
putImageData(datosImagen, x, y) :Este método convierte a los datos en datosImagen en una imagen y dibuja la imagen en el lienzo en la posición especificada por x e y. Este es el opuesto a getImageData().
createImageData(ancho, alto) :Este método crea datos para representar una imagen vacía. Todos sus pixeles serán de color negro transparente. Puede también recibir datos como atributo (en lugar de los atributos ancho y alto) y utilizar las dimensiones tomadas de los datos provistos para crear la imagen. 

La posición de cada valor en el array es calculada con la fórmula (ancho×4×y)+(x×4). Éste será el primer valor del pixel (rojo); para el resto tenemos que agregar 1 al resultado (por ejemplo, (ancho×4×y)+(x×4)+1 para verde, (ancho×4×y)+(x×4)+2 para azul, y (ancho×4×y)+(x×4)+3 para el valor alpha (transparencia). Veamos esto en práctica:
IMPORTANTE: Debido a restricciones de seguridad, no se puede extraer información del elemento <canvas> luego de que una imagen tomada desde una fuente externa fue dibujada en el lienzo. Solo cuando el documento y la imagen corresponden a la misma fuente (URL) el método getImageData() trabajará adecuadamente. Por este motivo, para probar este ejemplo tendrá que descargar la imagen desde nuestro servidor en www.minkbooks.com/content/snow.jpg (o usar una imagen propia), y luego subir esta imagen, el archivo HTML y el archivo con el código Javascript a su propio servidor. Si simplemente trata de ejecutar el siguiente ejemplo en su ordenador sin seguir los pasos previos, no funcionará.

Código 7-25. Generando un negativo de la imagen.

function iniciar(){
var elemento=document.getElementById('lienzo');
lienzo=elemento.getContext('2d');
var imagen=new Image();
imagen.src="snow.jpg";
imagen.addEventListener("load", modificarimagen, false);
}

function modificarimagen(e){
imagen=e.target;
lienzo.drawImage(imagen,0,0);
var info=lienzo.getImageData(0,0,175,262);
var pos;
for(x=0;x<=175;x++){
for(y=0;y<=262;y++){
pos=(info.width*4*y)+(x*4);
info.data[pos]=255-info.data[pos];
info.data[pos+1]=255-info.data[pos+1];
info.data[pos+2]=255-info.data[pos+2];
}
}
lienzo.putImageData(info,0,0);
}
window.addEventListener("load", iniciar, false);

Esta vez tuvimos que crear una nueva función (en lugar de utilizar una función anónima) para procesar la imagen luego de que es cargada. Primero, la función modificarimagen() genera una referencia a la imagen aprovechando la propiedad target usada en publicaciones anteriores. En el siguiente paso, usando esta referencia y el método drawImage(), la imagen es dibujada en el lienzo en la posición 0,0. No hay nada inusual en esta parte del código, pero eso es algo que pronto va a cambiar. 
IMPORTANTE: Los archivos para este ejemplo deben ser subidos a su propio servidor para trabajar correctamente (incluyendo la imagen snow.jpg que puede descargar desde www.minkbooks.com/content/snow.jpg). 
La imagen utilizada en nuestro ejemplo tiene un tamaño de 350 pixeles de ancho por 262 pixeles de alto, por lo que usando el método getImageData() con los valores 0,0 para la esquina superior izquierda y 175,262 para el valor horizontal y vertical, estamos extrayendo solo la mitad izquierda de la imagen original. Estos datos son grabados dentro de la variable info.
Una vez que esta información fue recolectada, es momento de manipular cada pixel para obtener el resultado que queremos (en nuestro ejemplo esto será un negativo de este trozo de la imagen).
Debido a que cada color es declarado por un valor entre 0 y 255, el valor negativo es obtenido restando el valor real a 255 con la fórmula color=255-color. Para hacerlo con cada pixel de la imagen, debemos crear dos bucles for (uno para las columnas y otro para las filas) para obtener cada color original y calcular el valor del negativo correspondiente.
El bucle for para los valores x va desde 0 a 175 (el ancho de la parte de la imagen que extrajimos del lienzo) y el for para los valores y va desde 0 a 262 (el tamaño vertical de la imagen y también el tamaño vertical del trozo de imagen que estamos procesando).

Luego de que cada pixel es procesado, la variable info con los datos de la imagen es enviada al lienzo como una imagen usando el método putImageData(). La imagen es ubicada en la misma posición que la original, reemplazando la mitad izquierda de la imagen original por el negativo que acabamos de crear. 
El método getImageData() retorna un objeto que puede ser procesado a través de sus propiedades (width, height y data) o puede ser usado íntegro por el método putImageData().
Existe otra manera de extraer datos del lienzo que retorna el contenido en una cadena de texto codificada en base64. Esta cadena puede ser usada luego como fuente para otro lienzo, como fuente de un elemento HTML (por ejemplo, <img>), o incluso ser enviado al servidor o grabado en un archivo. El siguiente es el método incluido con este fin: 

toDataURL(tipo) :El elemento <canvas> tiene dos propiedades, width y height, y dos métodos: getContext() y toDataURL(). Este último método retorna datos en el formato data:url conteniendo una representación del contenido del lienzo en formato PNG (o el formato de imagen especificado en el atributo tipo). 

Más adelante en esta serie de publicaciones veremos algunos ejemplos de cómo usar toDataURL() y cómo puede ayudarnos a integrar esta API con otras. 
Conceptos básicos: Los datos del tipo data:url son datos que son presentados en forma de cadena de texto y pueden ser incluidos en nuestros documentos como si se tratara de datos tomados de fuentes externas (por ejemplo, la fuente para imágenes insertadas con la etiqueta <img>). 

Patrones

Los patrones son simples adiciones que pueden mejorar nuestros trazados. Con esta herramienta podemos agregar textura a nuestras figuras utilizando una imagen. El procedimiento es similar a la creación de gradientes; los patrones son creados por el método createPattern() y luego aplicados al trazado como si fuesen un color. 
createPattern(imágen, tipo) El atributo imágen es una referencia a la imagen que vamos a usar como patrón, y tipo configura el patrón por medio de cuatro valores: repeat, repeat-x, repeat-y y no-repeat.

Código 7-26. Agregando un patrón para nuestro trazado.

function iniciar(){
var elemento=document.getElementById('lienzo');
lienzo=elemento.getContext('2d');
var imagen=new Image();
imagen.src="http://www.minkbooks.com/content/bricks.jpg";
imagen.addEventListener("load", modificarimagen, false);
}
function modificarimagen(e){
imagen=e.target;
var patron=lienzo.createPattern(imagen,'repeat');
lienzo.fillStyle=patron;
lienzo.fillRect(0,0,500,300);
}
window.addEventListener("load", iniciar, false);

Hágalo usted mismo: Experimente con los diferentes valores disponibles para createPattern() y también utilizando otras figuras.



Espero haber ayudado en algo. Hasta la próxima oportunidad!

DESCARGAR PUBLICACIÓN










  

No hay comentarios:

Publicar un comentario

       

Etiquetas

Academy (23) Accediendo a datos con ADO .NET (31) Acceso a la red (30) Algoritmo (34) Algoritmos en JAVA (2) Ampliación de clases (2) APRENDA A PROGRAMAR COMO SI ESTUVIERA EN PRIMERO - Autores : IKER AGUINAGA (3) APRENDA A PROGRAMAR COMO SI ESTUVIERA EN PRIMERO - Autores : IKER AGUINAGA (10) Aprendiendo a desarrollar en Windows 8 (5) Aprendiendo UML en 24 Horas (Autor : Joseph Schmuller ) (30) Arquitectura (29) Arquitectura del Computador (3) Arquitectura del Computador - Historia de la informática (1) Asignación de direcciones IP (18) Aspectos fundamentales de bases de datos (5) Auditoría de la dirección (2) Auditoría de Sistemas (3) Auditoría Informática - Un enfoque práctico - Mario G . Piattini y Emilio del Peso (7) Avanzado (23) Base de Datos (67) Básico (23) Bios (29) Business Productivity Online Suite - BPOS (3) Capa de Red (22) Capa de Transporte (16) Capítulo 1 - Documentos HTML5 (6) Capítulo 10. API Web Storage (2) Capítulo 11. API IndexedDB (4) Capítulo 12. API File (1) Capítulo 2. Estilos CSS y modelos de caja (7) Capítulo 3. Propiedades CSS3 (4) Capítulo 4. Javascript (6) Capítulo 5. Video y audio (6) Capítulo 6. Formularios y API Forms (8) Capítulo 7. API Canvas (5) Capítulo 8. API Drag and Drop (2) Capítulo 9. API Geolocation (2) CCNA1 v5.0 (195) CCNA1 v6.0 (23) CCNA2 v5.0 (26) CCNA3 v5.0 (25) CCNA4 v5.0 (23) CD-ROM (3) Chapter 1 How does Xamarin.Forms fit in? (7) Chapter 2 Anatomy of an app (5) Cisco (297) Cloud Computing (3) CNNA v5.0 Routing & Switching (216) CNNA v6.0 Routing & Switching (2) Codigo (2) Computadora (32) Configuración (29) Configuración de un sistema operativo de red (21) Control (29) Creación de tipos de datos y tablas (3) Creación y Administración de bases de datos (3) Creando la Interface de la Aplicación Windows (50) Creating Mobile Apps with Xamarin.Forms (13) Cuenta (29) Curso (32) Curso Aprendiendo a Programar (25) Datos (3) Desarrollando en Windows 8 - AVANZADO (2) Desarrollando en Windows 8 - BÁSICO (3) Desarrollando en Windows 8 - INTERMEDIO (2) Desarrollo (2) Desarrollo .Net (21) Desarrollo avanzado de Windows Store Apps usando C# (1) Desarrollo basado en conceptos de Ingeniería de Software para Visual Studio (2) DESARROLLO DE APLICACIONES WINDOWS CON MICROSOFT .NET (37) DESARROLLO DE APLICACIONES WINDOWS CON MICROSOFT .NET (Autor: Luis Dueñas Huaroto) (29) Desarrollo en Microsoft Visual Studio (44) Desarrollo en Microsoft Visual Studio - AVANZADO (15) Desarrollo en Microsoft Visual Studio - BÁSICO (14) Desarrollo en Microsoft Visual Studio - INTERMEDIO (18) Desarrollo en Windows Phone 8 (13) Diagnostico (4) Diagrama (3) Diagramas de actividades (2) Diagramas de colaboraciones (2) Diagramas de secuencias (2) Digital (2) Diplomado (2) Disco (29) Disco Duro (4) Diseño de aplicaciones de Windows 8 en HTML 5 (7) Dispositivos Electrónicos (11) Doctorado (2) Ejemplos (3) Ejemplos de algoritmos (27) El camino hacia el CSS3 (3) El diseño web flexible (6) El elemento de diseño Canvas (3) El enfoque de los sistemas (3) El flujo de un programa (2) El gran libro de HTML5 - CSS3 y Javascript - Autor: Juan Diego Gauchat (55) El principio de organicidad (7) Electrónica (2) Elementos de un sistema (5) Empresas (2) Entrada y salida (4) Entropía y neguentropía (7) Estrategia (2) Estructura de un programa Java (12) Estructuras de almacenamiento (10) Estructuras de control (6) Estructuras de las tablas en SQL Server (2) Estructuras fundamentales de los datos (2) Ethernet (21) Evolución y Familias de los Microprocesadores (15) Exámen (23) Exploración de la red (23) Extensión de clases (4) Facebook (4) Familia Intel (15) Forefront (8) Función (3) Funciones de una red (12) Funciones de una red informática (1) Fundamentos de C# para absolutos principiantes (17) Fundamentos de programación en Java (50) Generaciones de la computadora (5) Gestión (3) Gestión de riesgos - Auditoría de Sistemas (1) GONZALO MARTÍNEZ (1) Grupos Facebook (1) Harvard (29) Historia de las computadoras (11) HTML5 y CSS3 - Autor: Christophe Aubry (99) HTML5 y CSS3 aplicadal texto (7) HTML5 y CSS3 para los formularios (15) Imágenes (2) Implementación de Windows 7 (11) Información (31) Informática (29) Ingeniería (4) Instalar (29) Inteligencia (2) Inteligencia de Negocios con SQL Server (3) Intermedio (23) Internet (29) Internet Explorer 9 (3) Introducción a ASP.NET 5 (8) Introducción a Java (7) Introducción a jQuery (8) Introducción a la Auditoría de Sistemas (2) Introducción a la teoría general de sistemas (Oscar Johansen Bertoglio) (39) Introducción a Networking (2) Introducción a Window Forms (5) Introducción al acceso a datos con ADO .NET (9) Investigación de Operaciones (12) Java (52) Jump Start de consultas en las bases de datos de Microsoft SQL Server 2012 (8) La definición de un Sistema (6) La evolución del HTML y del CSS (3) La nueva sintaxis HTML5 (12) LA QUINTA DISCIPLINA en la práctica (Autor : Peter Senge) (28) Las animaciones en CSS3 (5) Las transformaciones CSS3 (11) Las transiciones con CSS3 (8) Licenciamiento Microsoft (3) Local Area Network (LAN) - Red de Area Local (2) Lógico (2) Los elementos de la estructura en html5 (9) Los elementos multimedia: audio y vídeo (2) Los estilos de caja en CSS3 (13) Los nuevos selectores de CSS3 (6) Maestría (2) Mantenimiento de Mouse y Teclado (2) Manual de Microsoft SQL Server - Full Transact SQL (68) Manual de soporte técnico para escuelas sobre windows 7 (42) Marco Teorico de Investigación de Operaciones (6) Medios de Almacenamiento (11) Medios de Networking (2) Mejorando la Interface de las Aplicaciones Windows (26) Memoria Tipos y Clases (5) Método (2) Metodología (1) Microsoft (324) Microsoft Lync 2010 (7) Microsoft Silverlight 4.0 (2) Microsoft Virtual Academy (356) Modelo (2) Modelo OSI y TCP-IP (2) Modelos con poco grado de dificultad de Programación Lineal - Investigación de Operaciones (13) Modelos con razonable grado de dificultad de Programación Lineal - Investigación de Operaciones (10) Modelos de desafio de Programación Lineal - Investigación de Operaciones (5) Modelos difíciles de Programación Lineal - Investigación de Operaciones (5) Modelos Fáciles de Programación Lineal - Investigación de Operaciones (13) Modelos lineales con solver (3) Modulo (23) Movimiento (2) Mozilla (29) MS SQL Server (77) MS Virtualization para Profesionales VMware - Gestión (3) MS Virtualization para Profesionales VMware- Plataforma (4) MVA (263) Negocio (2) Nivel Avanzado Desarrollo .Net (6) Nivel Básico Desarrollo .Net (11) Nivel Intermedio Desarrollo .Net (8) Normas técnicas peruanas y su evolución - Auditoría de Sistemas (1) Nube Privada - Avanzado (6) Nube Privada - Básico (6) Nube Privada - Intermedio (6) Office 365 (3) Optimización de Escritorio (10) Optimización de Escritorio - Avanzado (4) Optimización de Escritorio - Básico (3) Optimización de Escritorio - Intermedio (3) ORACLE 10g - ADMINISTRACIÓN Y ANÁLISIS (3) Oracle 10g y el Grid Computing (3) Organización aleatoria y secuencial (1) Partes principales de la Mainboard (12) Perceptron (2) Perfil (2) Periféricos de Entrada / Salida (15) Pesi (2) PHP y MySQL - Manual de aprendizaje para crear un sitio web - Autor : Olivier ROLLET (79) Plan (2) Plataforma (29) PMBOK (24) PMBOK - Guía de los fundamentos para la dirección de proyectos (24) PMBOK - INFLUENCIA DE LA ORGANIZACIÓN Y CICLO DE VIDA DEL PROYECTO (6) PMBOK - Introducción (11) PMBOK - PROCESOS DE LA DIRECCIÓN DE PROYECTOS (5) Prevención - Herramientas e Instrumentos de Medida (9) Principios básicos de enrutamiento y switching (169) Proceso (2) Proceso de auditoría de sistemas informáticos (2) Programación en Android - Auor : Salvador Gómez Oliver (46) Programación paso a paso de C# - Autor : Nacho Cabanes (16) Protocolos y comunicaciones de red (17) Proyecto (2) Qué es un sistema (4) Red de Área Local Inalámbrica (WLAN) (4) Redes (30) Redes inalámbricas - WIRELESS - Conocimiento general (15) Redes neuronales (2) Redes y Comunicaciones (45) Reparación de Fuentes - UPS - Estabilizadores (10) Reparación de Impresoras (9) Reparación de Monitores (16) Router (29) Seguridad en la Nube (3) Seminario (23) Server (24) Sharepoint 2010 - Nivel Básico (6) Sharepoint 2010 - Niveles Avanzados (18) Sharepoint 2010 - Niveles Avanzados - Básico (8) Sharepoint 2010 - Niveles Avanzados - Intermedio (9) Sinergia y recursividad (4) Sistema (33) Sistema de Cableado Estructurado (9) Software (30) SOLUCIÓN GRÁFICA DE MODELOS DE PROGRAMACIÓN LINEALES - INVOPE (8) Soporte a Infraestructura (3) SQL (38) SQL Azure - Introducción (3) Subsistemas de control (4) Tablas (4) Tarjeta Principal del Sistema (10) Tarjetas de Interfaces (7) Tecnología (31) Tecnologías LAN (1) TEORÍA GENERAL DE SISTEMAS (1) Tic (2) Tipo (2) TML5 y CSS3 - Autor: Christophe Aubry (12) Trabajando con el Formulario (7) Un diseño HTML5/CSS3: dConstruct 2011 (3) Un diseño HTML5/CSS3: FlipThru (2) Un diseño HTML5/CSS3: The Cat Template (2) Usando Controles Windows Forms (12) Usando Herramientas de Datos de Visual Studio (6) Ventas (2) Virtualización Hyper - V Nivel Básico (5) Virtualización Hyper - V Nivel Intermedio (5) What’s New in Windows 8.1 Security (4) Window (29) Windows 7 Segunda Fase - AVANZADO (4) Windows 7 Segunda Fase - BÁSICO (6) Windows 7 Segunda Fase - INTERMEDIO (4) Windows 8 - Vista Previa (4) Windows 8.1 To Go (2) Windows Azure (3) Windows Phone 7 (2) Windows Server 2008 R2 (3) Windows Server 2012 - Gestión y Automatización (3) Windows Server 2012 R2 Essentials (7) Windows Server 2012: Almacenamiento (5) Windows Server 2012: Identidad y Acceso (4) Windows Server 2012: Revisión Técnica (7) Xamarin (1)

Páginas vistas en total según Google