Get image (using paste) from the browser

杀马特。学长 韩版系。学妹 提交于 2020-12-26 04:50:25

问题


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

Example copy image - does not work

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.


回答1:


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>



回答2:


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);
    }
}


来源:https://stackoverflow.com/questions/60503912/get-image-using-paste-from-the-browser

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!