Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get image (using paste) from the browser

There are two ways to copy an image through the browser (for example chrome), the copy image and the copy address of the image.

When I copy the image address and paste it using my paste Image button, I can get the image copied from the base64 browser. But when I copy the image, I can't get the image. Is there a way to obtain the image using the image coipar, as shown in the examples?

Demo

code

  clickPaste() {
    let self = this;
    (navigator as any).clipboard.readText().then(clipboard => self.clip = clipboard);
console.log(self.clip) // copy image adress ---> base64
  }

Example copy image address - working image

image

Example copy image - does not work

image3

imag4

I know that copying the image and copying the image's address are different things, but I couldn't find out how I can get the image (blob or base64) when I use copy the image.

like image 605
John w. Avatar asked Feb 25 '26 02:02

John w.


2 Answers

You can access it from the paste ClipboardEvent's .clipboardData DataTransfer.

It will be in the .files FileList if available:

document.onpaste = (evt) => {
  const dT = evt.clipboardData || window.clipboardData;
  const file = dT.files[ 0 ];
  console.log( file );
};
img{ height: 100vh; }
<div contenteditable>You can paste the image here</div>
<figure>
  <figcaption>Copy this image</figcaption>
  <img src="https://upload.wikimedia.org/wikipedia/commons/4/47/PNG_transparency_demonstration_1.png">
</figure>

If you need to get it outside of such an event, then you will need to use the asynchronous Clipboard API.
Unfortunately, this API is not yet very well supported (currently Blink only), but anyway, here is how you can read an image file using this API.

You first need to request / check for the "clipboard-read" Permission.
Then if the request has not be denied, you can try to read the whole content of the clipboard by calling navigator.clipboard.read(). This will return a DataTransferItemsList (technically an Array), from which you will still have to pick the one that holds the .type you want to access.
In your case you only know it's an image, but there are several types available for images, so you need to determine which one it is while doing this check.

document.getElementById('btn').onclick = async (evt) => {
  const auth = await navigator.permissions.query( { name: "clipboard-read" } );
  if( auth.state !== 'denied' ) {
    const item_list = await navigator.clipboard.read();
    let image_type; // we will feed this later
    const item = item_list.find( item => // choose the one item holding our image
      item.types.some( type => { // does this item have our type
        if( type.startsWith( 'image/' ) ) {
          image_type = type; // store which kind of image type it is
          return true;
        }
      } )
    );
    const file = item && await item.getType( image_type );
    console.log( file );
  }
};
img{ height: 100vh; }
<button id="btn">read clipboard content</button>
<figure>
  <figcaption>Copy this image</figcaption>
  <img src="https://upload.wikimedia.org/wikipedia/commons/4/47/PNG_transparency_demonstration_1.png">
</figure>
like image 148
Kaiido Avatar answered Feb 27 '26 16:02

Kaiido


This is an example from this tutorial: First you add an event listener for "paste":

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

    // Handle the event
    retrieveImageFromClipboardAsBase64(e, function(imageDataBase64){
        // If there's an image, open it in the browser as a new window :)
        if(imageDataBase64){
            // data:image/png;base64,iVBORw0KGgoAAAAN......
            window.open(imageDataBase64);
        }
    });
}, false);

And using this funcion you can retrieve the image as base64:

**
 * This handler retrieves the images from the clipboard as a base64 string and returns it in a callback.
 * 
 * @param pasteEvent 
 * @param callback 
 */
function retrieveImageFromClipboardAsBase64(pasteEvent, callback, imageFormat){
    if(pasteEvent.clipboardData == false){
        if(typeof(callback) == "function"){
            callback(undefined);
        }
    };

    // retrive elements from clipboard
    var items = pasteEvent.clipboardData.items;

    if(items == undefined){
        if(typeof(callback) == "function"){
            callback(undefined);
        }
    };
    // loop the elements
    for (var i = 0; i < items.length; i++) {
        // Skip content if not image
        if (items[i].type.indexOf("image") == -1) continue;
        // Retrieve image on clipboard as blob
        var blob = items[i].getAsFile();

        // Create an abstract canvas and get context
        var mycanvas = document.createElement("canvas");
        var ctx = mycanvas.getContext('2d');

        // Create an image
        var img = new Image();

        // Once the image loads, render the img on the canvas
        img.onload = function(){
            // Update dimensions of the canvas with the dimensions of the image
            mycanvas.width = this.width;
            mycanvas.height = this.height;

            // Draw the image
            ctx.drawImage(img, 0, 0);

            // Execute callback with the base64 URI of the image
            if(typeof(callback) == "function"){
                callback(mycanvas.toDataURL(
                    (imageFormat || "image/png")
                ));
            }
        };

        // Crossbrowser support for URL
        var URLObj = window.URL || window.webkitURL;

        // Creates a DOMString containing a URL representing the object given in the parameter
        // namely the original Blob
        img.src = URLObj.createObjectURL(blob);
    }
}
like image 23
Dmyto Holota Avatar answered Feb 27 '26 15:02

Dmyto Holota