Saltar al contenido

Capturando una imagen de la webcam con PHP y la librería WebcamJS

Las nuevas posibilidades de HTML5 nos provee de muchas cosas interesantes con las que trabajar. Hay un proyecto llamado WebcamJS que permite obtener fotografías mediante la cámara web del usuario. Está muy bien documentado pero me gustaría mostrar un ejemplo básico para almacenar dichas imágenes en una base de datos MySQL y también en disco.

No voy a discutir el interminable almacenar las imágenes en el BDD versus sistema de archivos, cada quién sabe donde guarda sus cosas y como le funciona mejor, por eso incluyo los dos ejemplos que son muy similares. Realicé las pruebas en la última versión a la fecha de Firefox, Chrome, Opera y la versión 10 de Internet Explorer.

En este caso hipotético se le pide al usuario ingresar su nombre, número de identificación personal y una fotografía en vivo de su cámara web.

Definición de las tablas

Para almacenar las imágenes en la BDD:

CREATE TABLE `webcam_fotografias` (
 `dpi` varchar(13) CHARACTER SET utf8 NOT NULL COMMENT 'Número CUI del Documento Personal de Identificación',
 `nombre` varchar(45) CHARACTER SET utf8 NOT NULL COMMENT 'Nombre de la persona',
 `fotografia` longblob NOT NULL COMMENT 'Imagen almacenada de forma binaria',
 PRIMARY KEY (`dpi`)
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

Y para almacenarlas en el disco:

CREATE TABLE `webcam_disco` (
 `dpi` varchar(13) COLLATE utf8_unicode_ci NOT NULL COMMENT 'Número CUI del Documento Personal de Identificación',
 `nombre` varchar(45) COLLATE utf8_unicode_ci NOT NULL COMMENT 'Nombre de la persona',
 `archivo` varchar(255) COLLATE utf8_unicode_ci NOT NULL COMMENT 'Nombre de la imagen almacenada en el sistema de archivos/disco',
 PRIMARY KEY (`dpi`)
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

Porciones de código

El código no tiene comentarios ya que no es complicado, sin embargo me gustaría aclarar ciertos puntos.

Webcam.set({
    width: 320,
    height: 240,
    image_format: 'png'
});
Webcam.attach('#camara');

Aquí se define el ancho y alto de la imagen a capturar, el formato se ha definido como PNG. Para otras parámetros referirse a la documentación de WebcamJS. Lo que hace attach es usar el selector llamado camara para mostrar la “pantalla” de la cámara web.

Webcam.snap(function (data_uri) {
    document.getElementById('resultado').innerHTML = '<img src="' + data_uri + '" alt="" />';
    var raw_image_data = data_uri.replace(/^data\:image\/\w+\;base64\,/, '');
    document.getElementById('imagen').value = raw_image_data;
});

Al llamar a snap se captura la imagen actual de la cámara, luego se muestra en pantalla, en la siguiente línea se remueve el encabezado del contenido cifrado en Base4 y se insertan dichos datos en el campo oculto del formulario.

Los archivos almacenar_*.php contienen la línea:

$imagen_decodificada = base64_decode(filter_input(INPUT_POST, 'imagen'));

Acá se decodifica el campo imagen que contiene los datos enviados por el formulario. En almacenar_mysql.php se tiene:

$query->bindParam(':fotografia', $imagen_decodificada, PDO::PARAM_LOB);

La opción PDO::PARAM_LOB indica a PDO que ese campo va a recibir un objeto grande, en este caso es el binario que representa la imagen. Y en almacenar_disco.php:

$resultado = file_put_contents("imagenes/" . $archivo, $imagen_decodificada);

Indicamos que el contenido decodificado se debe almacenar en un archivo llamado $archivo bajo un directorio fijo.

Los archivos mostrar_*.php son básicamente lo mismo y su única diferencia radica en como se recupera la imagen. Para mostrar_mysql.php le anteponemos el encabezado:

data:image/png;base64,

Ya que sabemos que la imagen es PNG y será codificada en Base 64 para poder mostrarse directamente en la etiqueta IMG.

Oportunidades de mejora

  • Utilizar Ajax o el método upload de WebcamJS para transferir los elementos del formulario.
  • Si se va almacenar el binario en la BDD; permitir configurar el tipo de imagen (PNG o JPG) y salvar ese dato en la tabla.
  • Verificar las acciones de PHP y los errores en el proceso de salvado.

Recursos

  • El software que utilicé fue la librería WebcamJS 1.0, el servidor Web Apache 2.4.10, el lenguaje PHP 5.6.3 y el SGBDR MySQL 5.6.21
  • Acá está el zip con los archivos fuente y SQL.