codetc - 网站开发技术 首页 前端 查看内容

Vue实现压缩剪贴板图片功能

2020-2-8 19:40| 发布者: CODETC| 查看: 3998| 评论: 2

QQ或微信发送截图时都会对截图进行压缩,目的是为了预防存在剪切板中图片过大,产生上传速度慢问题,这里我们使用vue来试试实现对剪贴板中的图片进行压缩的功能。

实现思路

监听剪切板粘贴事件
从事件回调中获取clipboardData中的image对象声明一个变量接收该对象
使用reader.readAsDataURL方法加载clipboardData中的image对象
在reader.onload回调中获取图片base64码
创建Image对象,赋值图片base64码至当前对象的src属性
调用Image对象的onload函数,获取图片宽高等信息
声明canvas画布宽高分别为当前图片宽高除以缩放比例的值
使用drawImage方法绘制当前图片

实现过程

监听剪切板粘贴事件: 实现图片粘贴

const that = this;
document.body.addEventListener('paste', function (event) {
    that.$fullScreenLoading.show("读取图片中");
    // 获取当前输入框内的文字
    const oldText = that.$refs.msgInputContainer.textContent;
    // 读取图片
    let items = event.clipboardData && event.clipboardData.items;
    let file = null;
    if (items && items.length) {
        // 检索剪切板items
        for (let i = 0; i < items.length; i++) {
            if (items[i].type.indexOf('image') !== -1) {
                file = items[i].getAsFile();
                break;
            }
        }
    }
    // 预览图片
    const reader = new FileReader();
    reader.onload = function(event) {
        // 图片内容
        const imgContent = event.target.result;
        // 创建img标签
        let img = document.createElement('img');
        // 获取当前base64图片信息,计算当前图片宽高以及压缩比例
        let imgObj = new Image();
        let imgWidth = "";
        let imgHeight = "";
        let scale = 1;
        imgObj.src = imgContent;
        imgObj.onload = function() {
            // 计算img宽高
            if(this.width<400){
                imgWidth = this.width;
                imgHeight = this.height;
            }else{
                // 输入框图片显示缩小10倍
                imgWidth = this.width/10;
                imgHeight = this.height/10;
                // 图片宽度大于1920,图片压缩5倍
                if(this.width>1920){
                    // 真实比例缩小5倍
                    scale = 5;
                }
            }
            // 设置可编辑div中图片宽高
            img.width = imgWidth;
            img.height = imgHeight;
            // 压缩图片,渲染页面
            that.compressPic(imgContent,scale,function (newBlob,newBase) {
                // 删除可编辑div中的图片名称
                that.$refs.msgInputContainer.textContent = oldText;
                img.src = newBase; //设置链接
                // 图片渲染
                that.$refs.msgInputContainer.append(img);
                that.$fullScreenLoading.hide();
            });
        };
    };
    reader.readAsDataURL(file);
});

使用base64压缩图片

// 参数: base64地址,压缩比例,回调函数(返回压缩后图片的blob和base64)
compressPic:function(base64, scale, callback){
    const that = this;
    let _img = new Image();
    _img.src = base64;
    _img.onload = function() {
        let _canvas = document.createElement("canvas");
        let w = this.width / scale;
        let h = this.height / scale;
        _canvas.setAttribute("width", w);
        _canvas.setAttribute("height", h);
        _canvas.getContext("2d").drawImage(this, 0, 0, w, h);
        let base64 = _canvas.toDataURL("image/jpeg");
        // 当canvas对象的原型中没有toBlob方法的时候,手动添加该方法
        if (!HTMLCanvasElement.prototype.toBlob) {
            Object.defineProperty(HTMLCanvasElement.prototype, 'toBlob', {
                value: function (callback, type, quality) {
                    let binStr = atob(this.toDataURL(type, quality).split(',')[1]),
                        len = binStr.length,
                        arr = new Uint8Array(len);
                    for (let i = 0; i < len; i++) {
                        arr[i] = binStr.charCodeAt(i);
                    }
                    callback(new Blob([arr], {type: type || 'image/png'}));
                }
            });
        }else{
            _canvas.toBlob(function(blob) {
                if(blob.size > 1024*1024){
                    that.compressPic(base64, scale, callback);
                }else{
                    callback(blob, base64);
                }
            }, "image/jpeg");
        }
    }
}


文章来源 CODETC,欢迎分享,转载请注明地址: http://www.codetc.com/article-362-1.html
上一篇:HTTP状态码详解
发表评论

最新评论

引用 aa  2020-3-26 12:03
aa: aaa
pp
引用 aa  2020-3-26 12:02
aaa

查看全部评论(2)

 作为游客发表评论,请输入您的昵称

返回顶部