Hacer un selfie con JavaScript

En este tutorial vamos a ver cómo desarrollar una app con JavaScript que tome fotos utilizando la cámara de tu teléfono, portátil u ordenador. Te vamos a mostrar una serie de APIs nativas impresionantes que nos han permitido desarrollar nuestro proyecto sin ningún tipo de dependencias externas, librerías de terceros y demás parafernalias. Solo Javascript puro y duro.

La App

Para el usuario final, nuestra aplicación es sólo una versión simplificada de cualquier aplicación de fotos que puedes encontrar en cualquier smartphone. Utiliza el hardware de la cámara para tomar fotografías, eso es todo. Pero si hurgamos en las entrañas del programa, veremos que está ocurriendo una gran cantidad de magia JavaScript. Te describo, a grandes rasgos, el funcionamiento de la app:

  • Accedemos al input de la cámara y obtenemos el stream de vídeo mediante la API getUserMedia.
  • Proyectamos el stream de la cámara de vídeo en un elemento HTML.
  • Cuando el usuario quiera tomar una foto, copiamos el fotograma de vídeo actual y lo dibujamos en un elemento canvas.
  • Transformamos el lienzo en una imagen DataURL que luego se pueda mostrarse en la pantalla o descargarse como un archivo PNG.

En el artículo sólo veremos las partes más interesantes del código. Si quieres ver el código completo, puedes descargarlo desde aquí.

Accediendo a la cámara

JavaScript nos proporciona una API nativa para acceder a cualquier hardware de cámara mediante el método navigator.getUserMedia. Esta API trabaja solo en conexiones HTTPS seguras y siempre pide permiso al usuario antes de proceder.

Si el usuario da permiso para utilizar su cámara, navigator.getUserMedia nos dará un stream de vídeo en una devolución de llamada exitosa. Este stream consiste de los datos del raw broadcast que vienen de la cámara y necesitan ser transformados en un algo que sea reproducible con el método createObjectURL.

navigator.getUserMedia(
    // Options
    {
        video: true
    },
    // Success Callback
    function(stream){

        // Create an object URL for the video stream and
        // set it as src of our HTLM video element.
        video.src = window.URL.createObjectURL(stream);

        // Play the video element to show the stream to the user.
        video.play();
 
    },
    // Error Callback
    function(err){

        // Most common errors are PermissionDenied and DevicesNotFound.
        console.error(err);

    }
);

Tomando una foto

Una vez tenemos el stream de vídeo, podemos tomar fotografías con el input de la cámara. Esto se hace con un ingenioso truco que utiliza el poderoso elemento canvas para coger un frame del stream de vídeo en ejecución y lo guarda en un elemento img.

function takeSnapshot(){

    var hidden_canvas = document.querySelector('canvas'),
        video = document.querySelector('video.camera_stream'),
        image = document.querySelector('img.photo'),

        // Get the exact size of the video element.
        width = video.videoWidth,
        height = video.videoHeight,

        // Context object for working with the canvas.
        context = hidden_canvas.getContext('2d');


    // Set the canvas to the same dimensions as the video.
    hidden_canvas.width = width;
    hidden_canvas.height = height;

    // Draw a copy of the current frame from the video on the canvas.
    context.drawImage(video, 0, 0, width, height);

    // Get an image dataURL from the canvas.
    var imageDataURL = hidden_canvas.toDataURL('image/png');

    // Set the dataURL as source of an image element, showing the captured photo.
    image.setAttribute('src', imageDataURL); 

}

El elemento canvas en si mismo no necesita ser visible en el DOM. Estamos utilizando solamente la API de JavaScript como una manera de capturar un momento desde el video.

Descargando la foto

Por supuesto, no sólo queremos tomar selfies épicas sino que también queremos ser capaces de guardarlas para que las generaciones futuras puedan verlas. La forma más fácil de hacer esto es con el atributo download de los elementos a. El código HTML del botón de descarga sería el siguiente:

<a id="dl-btn" href="#" download="glorious_selfie.png">Save Photo</a>

El atributo download transforma nuestro hipervínculo en un botón de descarga. Su valor representa el nombre por defecto del archivo descargable, el archivo real a descargar lo definiremos en el atributo href, que, como puedes ver, está vacío por el momento. Para cargar nuestra foto que nos acabamos de echar aquí, podemos utilizar el image dataURL de la sección anterior:

function takeSnapshot(){

    //...

    // Get an image dataURL from the canvas.
    var imageDataURL = hidden_canvas.toDataURL('image/png');

    // Set the href attribute of the download button.
    document.querySelector('#dl-btn').href = imageDataURL;
}

Ahora, cuando alguien haga clic en este botón se le pedirá que descargue un archivo llamado glorious_selfie.png, que contiene la fotografía que se echó. Con esto, nuestro pequeño experimento está completo.

Esperamos que hayas aprendido mucho de este tutorial y que ahora te sientas inspirado para desarrollar aplicaciones de fotos super molonas. Como siempre, no dudes en hacer cualquier pregunta o en compartir cualquier idea con nosotros en la sección de comentarios.

Fuente: tutorialzine.com

COMPARTE ESTE ARTÍCULO

COMPARTIR EN FACEBOOK
COMPARTIR EN TWITTER
COMPARTIR EN LINKEDIN
COMPARTIR EN WHATSAPP