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


Posted in Javascript onFebruary 04, 2020

监听剪切板粘贴事件,读取剪切板中的图片文件,转成base64通过img标签显示出来,此时可能会存在剪切板中图片过大,产生上传速度慢问题,接下来就跟大家分享下如何将base64图片进行压缩。先跟大家展示下最终实现的效果:

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

实现思路

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

实现过程

本篇文章主要讲解剪切板图片压缩的实现,效果图中如何将剪切板的图片插入可编辑div以及如何发送,请移步我的另一篇文章: Vue解析剪切板图片并实现发送功能

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

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');//创建一个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");
      }
    }
  }

上述代码github地址: chat-system

总结

以上所述是小编给大家介绍的Vue实现剪切板图片压缩功能,希望对大家有所帮助!

Javascript 相关文章推荐
客户端脚本中常常出现的一些问题和调试技巧
Jan 09 Javascript
判断多个元素(RADIO,CHECKBOX等)是否被选择的原理说明
Feb 18 Javascript
Jquery+CSS3实现一款简洁大气带滑动效果的弹出层
May 15 Javascript
关于include标签导致js路径找不到的问题分析及解决
Jul 09 Javascript
JS实现网页Div层Clone拖拽效果
Sep 26 Javascript
JavaScript的Number对象的toString()方法
Dec 18 Javascript
对js eval()函数的一些见解
Aug 15 Javascript
微信小程序 出现47001 data format error原因解决办法
Mar 10 Javascript
深入理解ES6中let和闭包
Feb 22 Javascript
Django+Vue跨域环境配置详解
Jul 06 Javascript
详解elementUI中input框无法输入的问题
Apr 27 Javascript
微前端qiankun改造日渐庞大的项目教程
Jun 21 Javascript
Vue中keep-alive组件作用详解
Feb 04 #Javascript
WEB前端性能优化的7大手段详解
Feb 04 #Javascript
JavaScript对象属性操作实例解析
Feb 04 #Javascript
JavaScript this使用方法图解
Feb 04 #Javascript
解决微信小程序scroll-view组件无横向滚动的问题
Feb 04 #Javascript
JavaScript原型继承和原型链原理详解
Feb 04 #Javascript
JavaScript单线程和任务队列原理解析
Feb 04 #Javascript
You might like
一个取得文件扩展名的函数
2006/10/09 PHP
PHP+MYSQL会员系统的登陆即权限判断实现代码
2011/09/23 PHP
PHP实现QQ快速登录的方法
2016/09/28 PHP
PHP实现的自定义数组排序函数与排序类示例
2016/11/18 PHP
php获取文件名称和扩展名的方法
2017/02/07 PHP
php让json_encode不自动转义斜杠“/”的方法
2020/04/27 PHP
基于JQuery的cookie插件
2010/04/07 Javascript
Javascript 按位取反运算符 (~)
2014/02/04 Javascript
js中top的作用深入剖析
2014/03/04 Javascript
jQuery右下角旋转环状菜单特效代码
2015/08/10 Javascript
AngularJs $parse、$eval和$observe、$watch详解
2016/09/21 Javascript
js实现弹窗居中的简单实例
2016/10/09 Javascript
详解vue渲染函数render的使用
2017/12/12 Javascript
详解Webstorm 下的Angular2.0开发之路(图文)
2018/12/06 Javascript
重置Redux的状态数据的方法实现
2019/11/18 Javascript
element中el-container容器与div布局区分详解
2020/05/13 Javascript
原生js实现弹幕效果
2020/11/29 Javascript
小程序中手机号识别的示例
2020/12/14 Javascript
Python Web框架Flask中使用百度云存储BCS实例
2015/02/08 Python
pygame游戏之旅 添加游戏界面按键图形
2018/11/20 Python
python实现按行分割文件
2019/07/22 Python
Python线程条件变量Condition原理解析
2020/01/20 Python
tensorflow 实现自定义梯度反向传播代码
2020/02/10 Python
python生成大写32位uuid代码
2020/03/03 Python
Python之变量类型和if判断方式
2020/05/05 Python
利用python实现汉诺塔游戏
2021/03/01 Python
美国现代家具和家居商店:Apt2B
2016/08/29 全球购物
有750多个顶级品牌的瑞士时尚在线:ABOUT YOU
2017/01/04 全球购物
BIFFI美国站:意大利BIFFI BOUTIQUES豪华多品牌时装零售公司
2020/02/11 全球购物
PHP引擎php.ini参数优化深入讲解
2021/03/24 PHP
师范应届生教师求职信
2013/11/05 职场文书
不尊敬老师检讨书范文
2014/11/19 职场文书
2015年八一建军节活动总结
2015/03/20 职场文书
学校重阳节活动总结
2015/03/24 职场文书
2015年学校食堂工作总结
2015/04/22 职场文书
PyTorch 如何检查模型梯度是否可导
2021/06/05 Python