阅读 61

js获取剪切板图片大小变化的问题

需求描述

今天我这边有个需求是做一个简易素材上传管理的业务模块,想要满足用户复制图片到剪切板中,能够在我的页面中直接粘贴上传

实现方式

普遍采用的方式就是来监听paste事件,来获取剪切板里的文件

还有一种方式就是采用一个比较新的Clipboard API,这个需要通过用户同意之后,才可以使用

我试了一下,写法相对舒适一些,read方法会直接返回一个Promise,不过可能因为还比较新,支持性很不好,在Chrome里读取字符串没问题,读文件会返回一个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)
复制代码

发现问题

其中发现个问题,我复制了个2M的jpg图片,通过页面粘贴之后我输出了下文件大小,变成了12M多!

经过各种Google,也没有一个完全准确的解释,不过我猜测的话不是mac对复制到剪切板做了处理就是浏览器做了处理。我切换了不同的浏览器,发现文件大小果真不一样,所以我认为就是每个浏览器对剪切板中的文件都做了处理,而且发现blob中的文件类型是png,我上传的可是jpg啊!我又试了下png,文件大小的变化不大。

解决问题

既然被搞大了,肯定是要解决的。思路的话,转成base64肯定会更大了,我在想前端压缩一下吧,前端压缩的方式也就是用canvas了;我压缩了之后发现效果并不理想,质量设置太低了的话又容易失真。

后来我又想到把图片再转回成jpg的格式试一下,结果很惊喜,文件大小又回到了2M左右

不过我粘贴的时候已经被处理成png了,所以说我并不知道这个图片之前是什么格式的,也不能一股脑儿的都转成jpg,这样也不合理。

我又研究了下clipboardData里面的数据,发现items里面是有两条数据的,一个是file,一个是string,我在想这个string是不是就是文件名,又google一下,发现了getAsString这个方法,我获取了一下stringed内容,果然是文件的真实名字,这样图片的的真正格式就能取到了。

done!

2M jpg

png

第一张就是2M的jpg,第二张是860k的png,差距还是很大的

最后

目前还有两个功能没有找到实现的方法,一个是我在初始化的时候想要自动去读取剪切板里的图片,我用了document.execCommand('paste'),但实际上并没有触发;还有就是怎么做到一次性粘贴多张图片

这两个我还没有找到解决方法,欢迎大佬指路

关注下面的标签,发现更多相似文章
评论