Aprende a recuperar el contenido del portapapeles como una imagen con JavaScript en el navegador.

Cómo obtener las imágenes del portapapeles con JavaScript en el navegador

Como sabrás, la manipulación del portapapeles en la web no es una tarea fácil, ni siquiera para texto plano y mucho menos para imágenes. El contenido del portapapeles no se puede recuperar fácilmente con un método como clipboard.getContent. Si desea recuperar las imágenes en los navegadores más actualizados (sí, lo siento, pero 'no hay soporte para IE8), deberás confiar en el evento de pegar de la ventana:

Nota

El evento solo se puede activar mediante la acción del usuario en el documento, es decir, presionando CTRLV.

window.addEventListener("paste", function(thePasteEvent){
    // Utilice el objetoPasteEvent aquí ...
}, false);

Cuando presionas CTRLV y la ventana actual está enfocada, se activa este evento. Para usted es importante el objeto  thePasteEvent(parámetro recibido como argumento en la devolución de llamada) que contiene el clipboardDataobjeto. Si el clipboardDataobjeto existe, contendrá la itemspropiedad (por defecto indefinida si el portapapeles está vacío):

var items = pasteEvent.clipboardData.items;

Items es una matriz que contiene los datos del portapapeles, por lo que solo necesitarás recorrerlo. Si hay una imagen en el portapapeles, entonces el contenido se puede convertir a un archivo (Blob) que contiene una estructura similar a:

{
    name: "image.png", 
    lastModified: 1499172701225, 
    lastModifiedDate: Tue Jul 04 2017 14:51:41 GMT+0200 (W. Europe Daylight Time),
    webkitRelativePath: "", 
    size: 158453,
    type:"image/png",
    webkitRelativePath:""
}

Este objeto es el que necesita recuperar si desea mostrar la imagen en el navegador o enviarla a su servidor, etc. En los métodos que proporcionaremos para recuperar fácilmente la imagen del portapapeles, deberá proporcionar el thePasteEventcomo primer argumento del evento, de lo contrario no funcionarán.

En este artículo explicaremos cómo funciona el proceso para obtener la imagen del portapapeles y cómo recuperar la imagen en formato Blob o Base64.

Recuperar imagen como Blob

La forma más sencilla de recuperar la imagen del portapapeles es con el formato Blob (como un archivo). El siguiente método espera pasteEvent como primer argumento y una devolución de llamada como segundo argumento, que recibe como primer y único argumento, el blob de la imagen:

/**
 * Este controlador recupera las imágenes del portapapeles como un blob y las devuelve en una devolución de llamada.
 * 
 * @param pasteEvent 
 * @param callback 
 */
function retrieveImageFromClipboardAsBlob(pasteEvent, callback){
	if(pasteEvent.clipboardData == false){
        if(typeof(callback) == "function"){
            callback(undefined);
        }
    };

    var items = pasteEvent.clipboardData.items;

    if(items == undefined){
        if(typeof(callback) == "function"){
            callback(undefined);
        }
    };

    for (var i = 0; i < items.length; i++) {
        // Omitir contenido si no es imagen
        if (items[i].type.indexOf("image") == -1) continue;
        // Recuperar imagen en el portapapeles como blob
        var blob = items[i].getAsFile();

        if(typeof(callback) == "function"){
            callback(blob);
        }
    }
}

Luego, se puede usar de la siguiente manera, por ejemplo, para mostrar el Blob dentro de un lienzo en el documento:

<canvas style="border:1px solid grey;" id="mycanvas">

<script>
window.addEventListener("paste", function(e){

    // Maneja el evento
    retrieveImageFromClipboardAsBlob(e, function(imageBlob){
        // Si hay una imagen, muéstrela en el lienzo.
        if(imageBlob){
            var canvas = document.getElementById("mycanvas");
            var ctx = canvas.getContext('2d');
            
            // Crea una imagen para representar el blob en el lienzo
            var img = new Image();

            // Una vez que se carga la imagen, renderiza la imagen en el lienzo.
            img.onload = function(){
                // Actualizar las dimensiones del lienzo con las dimensiones de la imagen
                canvas.width = this.width;
                canvas.height = this.height;

                // Dibuja la imagen
                ctx.drawImage(img, 0, 0);
            };

            // Compatibilidad con varios navegadores para URL
            var URLObj = window.URL || window.webkitURL;

            // Crea un DOMString que contiene una URL que representa el objeto dado en el parámetro
            // especificamente, el Blob original
            img.src = URLObj.createObjectURL(imageBlob);
        }
    });
}, false);
</script>

Alternativamente, puede usar el Blob como lo necesite, esto es solo un ejemplo.

Recuperar imagen como base64

De forma predeterminada, el método retrieveImageFromClipboard devuelve un Blob (objeto similar a un archivo de datos sin procesar inmutables). Como solución alternativa, si necesita recuperar la imagen con el formato base64, puede usar la siguiente función (casi la misma que la original) que crea una cadena DOM a partir del blob y la establece como fuente a partir de una imagen que será renderizado a un lienzo. Como paso final, una vez que la imagen se carga en el lienzo abstracto (no será visible), la devolución de llamada devuelve la imagen en formato base64:

/**
 * Este controlador recupera las imágenes del portapapeles como una cadena base64 y las devuelve en una devolución de llamada.
 * 
 * @param pasteEvent 
 * @param callback 
 */
function retrieveImageFromClipboardAsBase64(pasteEvent, callback, imageFormat){
	if(pasteEvent.clipboardData == false){
        if(typeof(callback) == "function"){
            callback(undefined);
        }
    };

    var items = pasteEvent.clipboardData.items;

    if(items == undefined){
        if(typeof(callback) == "function"){
            callback(undefined);
        }
    };

    for (var i = 0; i < items.length; i++) {
        // Omitir contenido si no es imagen
        if (items[i].type.indexOf("image") == -1) continue;
        // Recuperar imagen en el portapapeles como blob
        var blob = items[i].getAsFile();

        // Crea un lienzo abstracto y obtén contexto
        var mycanvas = document.createElement("canvas");
        var ctx = mycanvas.getContext('2d');
        
        // Crea una imagen
        var img = new Image();

        // Una vez que se carga la imagen, renderiza la imagen en el lienzo.
        img.onload = function(){
            // Actualizar las dimensiones del lienzo con las dimensiones de la imagen
            mycanvas.width = this.width;
            mycanvas.height = this.height;

            // Dibuja la imagen
            ctx.drawImage(img, 0, 0);

            // Ejecute la devolución de llamada con el URI base64 de la imagen
            if(typeof(callback) == "function"){
                callback(mycanvas.toDataURL(
                    (imageFormat || "image/png")
                ));
            }
        };

        // Compatibilidad con varios navegadores para URL
        var URLObj = window.URL || window.webkitURL;

        // Crea un DOMString que contiene una URL que representa el objeto dado en el parámetro
        // especificamente el Blob original
        img.src = URLObj.createObjectURL(blob);
    }
}

Y se puede utilizar de la siguiente manera:

window.addEventListener("paste", function(e){

    // Maneja el evento
    retrieveImageFromClipboardAsBase64(e, function(imageDataBase64){
        //Si hay una imagen, ábrala en el navegador como una nueva ventana :)
        if(imageDataBase64){
            // data:image/png;base64,iVBORw0KGgoAAAAN......
            window.open(imageDataBase64);
        }
    });
}, false);

Ejemplo

Pruebe un ejemplo en vivo en el siguiente fiddle:

Que te diviertas ❤️!


Ingeniero de Software Senior en EPAM Anywhere. Interesado en la programación desde los 14 años, Carlos es un programador autodidacta, fundador y autor de la mayoría de los artículos de Our Code World.

Conviertete en un programador más sociable

Patrocinadores