Getting a screenshot of the clipboard with JavaScript

- Andrés Cruz

En español
Getting a screenshot of the clipboard with JavaScript

Example Download

In this entry we will see how to copy an image from a screenshot that is temporarily saved on the clipboard or clipboard in an <img> element.

We will also see how we can send this image through Ajax for processing and saving on the server; Below is the table of contents:

  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…
  3. 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 Capturing a computer screen

Many Linux distributions such as Fedora offer applications from which we can take screenshots:

captura de pantalla aplicación

That allow you to save an image resulting from the screenshot to some location on the computer or on the clipboard; the latter is part of our case of interest.

You can also use the F12 key or the PrintScreen key provided on many keyboards; although these actions may not copy the image to the clipboard or may not even work on certain operating systems.

2.0 Saving the screenshot in an <img> element with JavaScript

Once we have taken the screenshot to the clipboard, we must define an event that allows us to capture the moment when we copy some content to a website using:

  1. The Ctrl + V combination on our keyboard.
  2. Selecting the paste option from our browser.
  3. In the pop-up menu, click on the paste option.

More info: w3schools.

2.1 The paste event in JavaScript

The JavaScript API provides an event that allows you to capture the paste event through the following line of code:

window.addEventListener("paste", pasteEvent);

2.2 Defining our function to capture the event

Now we can define the function called pasteEvent() that will be executed when any of the events mentioned above occur; this function allows you to copy the contents of the clipboard into an element of type <img>; Let's see the complete definition of the function:

          window.addEventListener("paste", processEvent);

            function processEvent(e) {

                for (var i = 0; i < e.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 Explaining the previous function…

ClipboardEvent.clipboardData to read clipboard data

The clipboardData object allows access in read-only mode to the data contained in the clipboard through an Array of items; we can also find the type of data (which can be text, images, etc.) that is in a certain position of the Array.

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

Once we have the item to evaluate; we determine the type of data and the stored data respectively:

  • We query the type through the type type.indexOf("image") method.
  • We obtain the BLOB data (raw data) through the getAsFile() method clipboardItem.getAsFile().

After inspecting the data type and obtaining the same, it is necessary to convert the data from a BLOB object to a DOMString using the createObjectURL() method that creates a URL that represents the object, so that the image can be rendered into an element of type <img>:

var blobUrl = URL.createObjectURL(blob);  

Finally we copy the content of the image from the screenshot into an <img> element:

img.attr("src", blobUrl);

2.4 Final result of the experiment

Copy the image you have to the clipboard with Ctrl + V or another mode.

3. Sending the image copied from the clipboard to the server with Ajax

3.1 Saving the image on the server

A useful use of the experiment presented above is to be able to save the image already generated and saved in an <img> element on the server; For this we can use Ajax or a form in the traditional way; although before we can save the image on the server we must process it so that it can be handled correctly.

3.2 Generating a base64 encoded string of the image on the server

At this point, if we check the source src attribute of the image:

src img

We will realize that it is nothing more than a value that represents our image, but it does not offer us any information about it; In order to save an image on the server, it is not possible to use a BLOB type or the URL that represents it; We must encode it in base64 so that the image can be easily processed from the server.

We can easily convert our image from a BLOB type to base64 with the following 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) {}
            });
            }

The objet FileReader()

First we create an object of type FileReader() that allows reading files asynchronously.

Once the file (our image) is read, the result property will read the contents of the file/image already encoded in base64.

Once our image has been encoded, it is possible to send the image encoded in base64 by Ajax or through a field in a form.

3.3 How to save the image in base64 in our database?

Once our base64 encoded image is obtained on the server side, it must be decoded; If we use Java Web we can use the following function to decode the base64 image to a byte array:

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

In PHP there is a similar function:

$data = base64_decode($data);

Once the image is decoded, the database can be saved as if it were any other file obtained from the server by a file type input.

Considerations

Depending on the decoding function to be used, it may be necessary to remove the data:image/png;base64 header present in our base64-encoded image; this applies to the Base64.decodeBase64 function in Java; if this header is left, the image could be decoded with errors and therefore the file would be corrupted.

Example Download

Andrés Cruz

Desarrollo con Laravel, Django, Flask, CodeIgniter, HTML5, CSS3, MySQL, JavaScript, Vue, Android, iOS, Flutter

Andrés Cruz en Udemy

Acepto recibir anuncios de interes sobre este Blog.