DesarrolloLibre

Desarrollo Web, Android, juegos y mucho más

Categorias
29-01-2015

En esta entrada veremos como copiar una imagen producto de una captura de pantalla que se encuentre guardada de manera temporal en el portapapeles o clipboard en un elemento <img>.

Además veremos como podemos enviar esta imagen a través de Ajax para su procesamiento y guardado en el servidor; a continuación, la tabla de contenido:

  1. Capturando la pantalla de un ordenador
  2. Guardando la captura de pantalla en un elemento con JavaScript
    1. El evento paste en JavaScript
    2. Definiendo nuestra función para capturar el evento
    3. Explicando la función anterior…
  • Enviando la imagen copiada del clipboard al servidor con Ajax
    1. Guardando la imagen en el servido
    2. Generando un string codificado en base64 de la imagen en el servidor
    3. ¿Cómo guardar la imagen en base64 en nuestra base de datos?
  • 1.0 Capturando la pantalla de un ordenador

    Muchas distribuciones en Linux como Fedora ofrecen aplicaciones desde las cuales podemos realizar capturas de pantallas:

    captura de pantalla aplicación

    Que permiten guardar una imagen producto de la captura de pantalla en alguna ubicación en la computadora o en el portapapeles; este último es parte de nuestro caso de interés.

    También se pueden usar la tecla F12 o la tecla ImprPant provista en muchos teclados; aunque es posible que estas acciones no copien la imagen en el portapapeles o inclusive que no funcionen en determinados sistemas operativos.

    2.0 Guardando la captura de pantalla en un elemento <img> con JavaScript

    Una vez que nos hayamos hecho con la captura de pantalla en el portapapeles, debemos definir un evento que permita capturar el momento cuando copiamos algún contenido en un sitio web mediante:

    Más información en la w3schools.

    2.1 El evento paste en JavaScript

    La API de JavaScript provee un evento que permite capturar el evento paste/pegar a través de la siguiente línea de código:

    window.addEventListener("paste", pasteEvent);
        

    2.2 Definiendo nuestra función para capturar el evento

    Ahora podemos definir la función llamada pasteEvent() que se ejecutará cuando ocurra alguno de los eventos mencionados anteriormente; dicha función permite copiar el contenido del portapapeles en un elemento de tipo <img>; veamos la definición completa de la función:

              window.addEventListener("paste", processEvent);
    
                function processEvent(e) {
    
                    for (var i = 0; i clipboardData.items.length; i++) {
                        // get the clipboard item
                        // obtengo el clipboard item
                        var clipboardItem = e.clipboardData.items[0];
                        var type = clipboardItem.type;
    
                        // verifico si es una imagen
                        if (type.indexOf("image") != -1) {
    
                            // obtengo el contenido de la imagen BLOB
                            var blob = clipboardItem.getAsFile();
                            console.log("blob", blob);
                            // creo un la URL del objeto
                            var blobUrl = URL.createObjectURL(blob);
                            console.log("blobUrl", blobUrl);
                            // agrego la captura a mi imagen
                            document.getElementsByTagName("img")[0].setAttribute("src", blobUrl);
    
                        } else {
                            console.log("No soportado " + type);
                        }
                    }
                }
        

    2.3 Explicando la función anterior…

    ClipboardEvent.clipboardData para leer los datos del portapapeles

    El objeto clipboardData permite acceder en modo sólo lectura a la data contenida en el portapapeles a través de un Array de items; También podemos encontrar el tipo de datos (el cual puede ser texto, imágenes, etc) que se encuentra en una posición determinada del Array.

    var clipboardItem = e.clipboardData.items[i];
        

    Una vez que tengamos el item a evaluar; determinamos el tipo de data y la data almacenada respectivamente:

    Luego de inspeccionar el tipo de data y obtenida la misma, es necesario convertir la data de un objeto BLOB a un DOMString empleando el método createObjectURL() que crea una URL que representa el objeto, para que la imagen pueda ser reenderizada en un elemento de tipo <img>:

    var blobUrl = URL.createObjectURL(blob);
        

    Finalmente copiamos el contenido de la imagen proveniente de la captura de pantalla en un elemento <img>:

    img.attr("src", blobUrl);
        

    2.4 Resultado final del experimento

    Copia la imagen que tengas en el portapapel con Ctrl + V u otra modalidad.

    3. Enviando la imagen copiada del clipboard al servidor con Ajax

    3.1 Guardando la imagen en el servidor

    Un uso útil del experimento presentado anteriormente consiste en poder guardar la imagen ya generada y guardada en un elemento <img> en el servidor; para esto podemos emplear Ajax o un formulario de la manera tradicional; aunque antes de poder guardar la imagen en el servidor debemos procesarla para que pueda ser manejada correctamente.

    3.2 Generando un string codificado en base64 de la imagen en el servidor

    Llegado a este punto, si verificamos el atributo source src de la imagen:

    src img

    Nos daremos cuenta que no es más que un valor que representa nuestra imagen, más no nos ofrece ninguna información sobre la misma; para poder guardar una imagen en el servidor no es posible emplear un tipo BLOB o la URL que lo represente; debemos de codificar la misma en base64 para que la imagen pueda ser procesada fácilmente desde el servidor.

    Podemos convertir nuestra imagen fácilmente de un tipo BLOB a base64 con el siguiente script:

                var reader = new window.FileReader();
                reader.readAsDataURL(clipboardItem.getAsFile());
                
                reader.onload = function() {
                    console.log(reader.result.replace('data:image/png;base64,', '')
                            .toString()
                    $.ajax({
                        type: 'POST',
                        url: URL,
                        data: {
                            'pantalla': reader.result
                                    .replace('data:image/png;base64,', '').toString(),
                        },
                        success: function(response) {}
                });
                }
        

    El objeto FileReader()

    Primero creamos un objeto de tipo FileReader() que permite leer archivos de manera asíncrona.

    Una vez leído el archivo (nuestra imagen) la propiedad result para leer el contenido del archivo/imagen ya codificado en base64;.

    Una vez codificada nuestra imagen, es posible enviar la imagen codificada en base64 por Ajax o a través de un campo en un formulario.

    3.3 ¿Cómo guardar la imagen en base64 en nuestra base de datos?

    Una vez obtenida nuestra imagen codificada en base64 en el lado del servidor se debe de decodificar la misma; si empleamos Java Web podemos usar la siguiente función para decodificar la imagen en base64 a un arreglo de byte:

    byte imagen[] = Base64.decodeBase64(imageString);
        

    En PHP existe una función similar:

    $data = base64_decode($data);
        

    Ya decodificada la imagen se puede guardar el base de datos como si se tratase de cualquier otro archivo obtenido en el servidor por un input de tipo file.

    Consideraciones

    Dependiente de la función empleada para decodificación a emplear puede ser necesario retirar la cabecera data:image/png;base64 presente en nuestra imagen codificada en base64; esto se aplica en para la función Base64.decodeBase64 en Java, en caso de dejarse esta cabecera la imagen podría decodificarse con errores y por lo tanto el archivo estaría corrupto.


    Publicidad

    Give me for a beer!

    Algunos recursos que te pueden interesar

    Eye Candy

    Eye Candy

    Circunferencia animada con Canvas

    Circunferencia animada con Canvas

    Efectos hover con CSS

    Efectos hover con CSS

    Algunos artículos que te pueden interesar

    Primeros pasos con SQLite en JavaScript: los métodos openDatabase, executeSql y executeSql

    Primeros pasos con SQLite en JavaScript: los métodos openDatabase, executeSql y executeSql

    Con SQLite en HTML5 se puede almacenar información persistente de distintos tipos (del usuario, control, etc) con JavaScript empleando los métodos openDatabase, executeSql y executeSql.

    Andrés Cruz 18-01-2016

    Los mejores plugin WYSIWYG para JavaScript

    Los mejores plugin WYSIWYG para JavaScript

    Se presentan algunos plugins gratuitos WYSIWYG para JavaScript que no son más que una interfaz que permite dar formato al texto introducido mediante HTML; en esencia permite enriquecer el texto introducido mediante un procesador de texto.

    Andrés Cruz 28-03-2016

    Detectando los eventos de teclado con Canvas

    Detectando los eventos de teclado con Canvas

    En esta entrada veremos un pequeño experimento en donde con el Canvas mediante los eventos de teclados específicamente emplearemos las flechas de direcciones del teclado.

    Andrés Cruz 07-12-2015