Requirements describe

Today, I have a demand to make a simple material upload management business module, I want to meet the needs of users to copy pictures to the clipboard, can directly paste and upload in my page

implementation

A common way to do this is to listen for paste events to get files from the clipboard

Another option is to use a newer Clipboard API, which requires user approval before being used

The “read” method returns a Promise, but it’s still relatively new and doesn’t support it very well. In Chrome, you can read a string, but reading a file returns a ClipboardItem.

Clipboard API

document.addEventListener('paste', (e) => {
    const cbd = e.clipboardData
    for (let i = 0; i < cbd.items.length; i++) {
        const item = cbd.items[i]
        if (item.kind === 'file') {
            const blob = item.getAsFile()
            if(! blob || blob.size ===0) {
                return}}}},false)
Copy the code

Found the problem

I found a problem, I copied a 2M JPG image, after pasting through the page I output the file size, became more than 12M!

After all Google, there is no exact explanation, but MY guess is that either the MAC did something to copy to the clipboard or the browser did something to copy to the clipboard. I switched between different browsers and found that the file sizes were really different, so I assumed that each browser was doing something to the clipboard and found that the bloB was PNG and I was uploading JPG. I tried PNG again and the file size didn’t change much.

To solve the problem

Well, if it’s a mess, it has to be fixed. If you switch to base64, it will definitely be bigger. I am thinking about front-end compression. The way of front-end compression is to use Canvas; After I compressed it, I found that the effect was not ideal, and the quality setting was too low and easy to distort.

Later, I thought of converting the image back to JPG format to try again, and the result was very surprising, and the file size was back to about 2M

However, when I paste it, it has been processed into PNG, so I don’t know what format the image used to be, nor can I convert it to JPG all at once, which doesn’t make sense.

I studied the data in clipboardData again and found that there were two data in items, one was File and the other was string. I was wondering whether the string was the file name, and I googled and found the method getAsString. I get the stringed content, and sure enough, the real name of the file, so that the real format of the image can be retrieved.

Done!

The first image is the JPG of 2M, and the second image is the PNG of 860K, which is still a big gap

The last

There are still two functions that I haven’t found a way to implement. One is that I want to automatically read images from the clipboard during initialization. I use Document. execCommand(‘paste’), but it doesn’t actually trigger. There is how to paste more than one picture at a time

I have not found a solution to these two, welcome the boss to guide