El componente PhotoCam de Primefaces: hazte una foto con la webcam.

7
18157

El componente PhotoCam de Primefaces: hazte una foto con la webcam.

0. Índice de contenidos.


1. Introducción

Primefaces es una librería de componentes para JSF. Con la gran cantidad de componentes que cuenta esta librería podemos añadir muchísima funcionalidad en el front-end de nuestras aplicaciones.

Muchas aplicaciones, cuentan con una sección de registro de nuevos usuarios. A menudo, en dicha sección, se ofrece la posibilidad al usuario de subir una foto o hacerse una con la webcam. En este tutorial vamos a ver cómo preparar nuestra aplicación JSF con Primefaces para que permita que los usuarios utilicen su webcam para hacerse una foto gracias al componente PhotoCam. Nótese que este componente estará disponible a partir de la versión 3.1 de Primefaces y, de momento, no es compatible con Internet Explorer (¿todavía hay alguien que se sorpenda?).


2. Entorno.

El tutorial está escrito usando el siguiente entorno:

  • Hardware: Portátil MacBook Pro 15′ (2.2 Ghz Intel Core I7, 8GB DDR3).
  • Sistema Operativo: Mac OS Snow Leopard 10.6.7
  • Entorno de desarrollo: Eclipse 3.7 Indigo.
  • JSF 2.1.3.
  • Primefaces 3.1-SNAPSHOT.
  • Mozilla Firefox 9.


3. El problema.

Supongamos que tenemos que hacer una pequeña aplicación donde la gente pueda dar de alta los datos de su mascota. Serán necesarios los siguientes datos para poder registar al animal en el sistema:

  • El nombre de la mascota.
  • Su edad.
  • Una foto hecha por la webcam del ordenador.

Cualquiera que se haya pegado un poco con JSF y/o Primefaces sabrá que crear un formulario donde se recojan los dos primeros datos no es ningún problema pero, ¿y la foto tomada desde la webcam?

Por suerte el componente PhotoCam de Primefaces nos da una solución a este problema.


4. Manejando la petición.

Lo primero que haremos será crear nuestro controlador que, manejará las peticiones: fotos tomadas desde la webcam, nombre y edad de la mascota.


package com.autentia.tutoriales.prueba_photocam;

import java.io.File;
import java.io.IOException;

import javax.faces.FacesException;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import javax.imageio.stream.FileImageOutputStream;
import javax.servlet.ServletContext;

import org.primefaces.event.CaptureEvent;

@ManagedBean
@ViewScoped
public class PhotoCamBean {

	private String nombre;

	private int edad;

	private String foto;

	public void oncapture(CaptureEvent captureEvent) {

		// obtenemos los datos de la foto como array de bytes
		final byte[] datos = captureEvent.getData();

		final ServletContext servletContext = (ServletContext)FacesContext.getCurrentInstance().getExternalContext()
				.getContext();
		// le asignamos el nombre que sea a la imagen (en este caso siempre el mismo)
		this.foto = "foto.png";
		// ruta destino de la imagen /photocam/foto.png
		final String fileFoto = servletContext.getRealPath("") + File.separator + "photocam" + File.separator + foto;

		FileImageOutputStream outputStream = null;
		try {
			outputStream = new FileImageOutputStream(new File(fileFoto));
			// guardamos la imagen
			outputStream.write(datos, 0, datos.length);
		} catch (IOException e) {
			throw new FacesException("Error guardando la foto.", e);
		} finally {
			try {
				outputStream.close();
			} catch (IOException e) {
			}
		}
	}

	public void guardarDatos() {
		// hacemos lo que sea con los datos...
	}

	public String getFoto() {
		return foto;
	}

	public boolean isVerFoto() {
		return foto != null;
	}

	public String getNombre() {
		return nombre;
	}

	public void setNombre(String nombre) {
		this.nombre = nombre;
	}

	public int getEdad() {
		return edad;
	}

	public void setEdad(int edad) {
		this.edad = edad;
	}

}


5. El formulario.

Pues bien, lo siguiente será crear el formulario de recogida de datos:


<?xml version="1.0" encoding="UTF-8"?>

<html xmlns="http://www.w3.org/1999/xhtml"
	xmlns:ui="http://java.sun.com/jsf/facelets"
	xmlns:h="http://java.sun.com/jsf/html"
	xmlns:f="http://java.sun.com/jsf/core"
	xmlns:p="http://primefaces.org/ui">

<f:view contentType="text/html">

	<h:head>
		<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
		<title>Prueba PhotoCam</title>
		<style type="text/css">
			table td {
				vertical-align: top;
			}
		</style>
	</h:head>

	<h:body>
		<h:form>
			<p:panel header="Introduce los datos de tu mascota">
				<h:panelGrid columns="2">
					<h:outputLabel for="nombre" value="Nombre" />
					<p:inputText id="nombre" value="#{photoCamBean.nombre}" />
					<h:outputLabel for="edad" value="Edad" />
					<p:inputText id="edad" value="#{photoCamBean.edad}" />
					<h:outputLabel for="fotoLink" value="Foto" />
					<p:commandLink id="fotoLink" onclick="fotoDialog.show()">
						<p:graphicImage value="#{pageContext.contextPath}/img/webcam.png"
							rendered="#{! photoCamBean.verFoto}" />
						<p:graphicImage rendered="#{photoCamBean.verFoto}"
							value="#{pageContext.contextPath}/photocam/#{photoCamBean.foto}"
							cache="false" />
					</p:commandLink>
				</h:panelGrid>
				<p:commandButton action="#{photoCamBean.guardarDatos}"
					value="Guardar" />
			</p:panel>
			<p:dialog header="Haz una foto" widgetVar="fotoDialog" modal="true"
				fixedCenter="true" width="400" visible="false" resizable="false">
				<p:photoCam widgetVar="pc" listener="#{photoCamBean.oncapture}"
					update="fotoLink" />
				<br />
				<p:commandButton type="button" value="Hacer foto"
					onclick="pc.capture()">
					<p:ajax oncomplete="fotoDialog.hide();" />
				</p:commandButton>
			</p:dialog>

		</h:form>
	</h:body>
</f:view>
</html>
	

Este sería el aspecto que presentaría el formulario:

Pulsando sobre la pequeña imagen que aparece a continuación del literal «Foto» nos aparecerá un cuadro de diálogo que nos permitira tomarnos la foto desde la webcam.

Nos aparecerá una advertencia de seguridad para que demos permiso a la aplicación a utilizar nuestra webcam. Como puede verse, el componente PhotoCam hace uso de «Adobe Flash Player», por lo que es necesario tener el plugin instalado en nuestro navegador. Una vez hayamos permitido el acceso a la cámara, estaremos listos para tomar la instantánea.

Y el siguiente paso es, ponernos guapos (o a nuestra mascota) y pulsar el botón «Hacer Foto». Después de llevarme un par de bocados de mi perro, lo acabé consiguiendo :-S


6. ¿Qué ha pasado?.

Pues lo que ha pasado es muy sencillo, el componente p:photoCam enviará la imagen capturada a nuestro ManagedBean una vez se haya pulsado el botón «Hacer foto». Se producirá un evento que será capturado con el método oncapture, que recibirá un elemento CaptureEvent con los datos de la imagen como array de bytes.

Lo que estamos haciendo es guardar esa imagen en disco y actualizar la vista (elemento fotoLink) para que muestre la imagen tomada que será accesible desde http://loquesea/photocam/foto.png. Posteriormente, cuando el usuario pulse el botón «Guardar», se invocará al método guardarDatos donde finalizaremos el proceso de registro.


7. Referencias.


8. Conclusiones.

En este tutorial hemos visto cómo funciona el componente PhotoCam de la librería de Primefaces para JSF. Como hemos apreciado es realmente sencillo utilizar este componente para utilizarlo como controlador de nuestra webcam. Creedme si os digo que casi me ha costado más conseguir que mi perro se estuviese quieto delante de la cámara que escribir este tutorial 🙂

No obstante, debemos recordar que este componente no estará disponible hasta la versión 3.1. Además, vuelvo a remarcar que no funciona en Internet Explorer por lo que, si estamos pensando en usarlo en una aplicación, deberíamos informar al usuario de que cambie de navegador si está usando IE y quiere hacerse una foto usando la webcam.

Espero que este tutorial os haya sido de ayuda. Un saludo.

Miguel Arlandy

marlandy@autentia.com

Twitter: @m_arlandy

7 COMENTARIOS

  1. hola, me parece muy bueno el tutorial, he implementado la captura de imagenes desde mi aplicación y ya las guarda en la base, existe alguna forma de no mostrar al usuario q se le esta fotografiando?, me explico, la aplicación que tengo es para tomar exámenes y durante el examen se toma fotos, pero no tengo que mostrarle eso al usuario… espero me puedan ayudar

    • Aunque sea tarde…
      La aplicación toma una foto y guarda el archivo en el disco duro en una ruta dentro del servidor que contiene a la aplicación…Solo borrar del xhtml el componente que es el que muestra la foto. (Y)

      Ahora ayudenme a mi. Hice una aplicación que sera usada en una tablet pero por defecto el Chrome o quiza la librería usa la camara frontal y yo quiero usar la camara trasera! no sé como cambiar eso. Se van a tomar fotos a telas, es necesario que se use la camara trasera ayuda!!! T_T

  2. Hola Majorie Torres

    He realizado la misma aplicación pero no he podido almacenarla la fotografía en la bd mysql, usted podría indicarme como hacerlo?. Gracias

  3. Hola, toma la foto, la guarda pero no renderiza, es decir, no la muestra en la pantalla, veo el código (la consola) y me sale photocam.js.jsf?ln=primefaces&v=5.0:1 Uncaught TypeError: Cannot read property ‘call’ of undefined. ¿A qué se debe, qué estoy haciendo mal?

  4. Hola, hice una app que captura fotos, pero solo funciona con camaras web, si conecto una cámara digital y la quiero usar como ver, no me deja. ¿Hay alguna forma de hacer esto?

    Saludos

DEJA UNA RESPUESTA

Por favor ingrese su comentario!

He leído y acepto la política de privacidad

Por favor ingrese su nombre aquí

Información básica acerca de la protección de datos

  • Responsable:
  • Finalidad:
  • Legitimación:
  • Destinatarios:
  • Derechos:
  • Más información: Puedes ampliar información acerca de la protección de datos en el siguiente enlace:política de privacidad