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 相关文章推荐
js null,undefined,字符串小结
Aug 21 Javascript
JQUERY设置IFRAME的SRC值的代码
Nov 30 Javascript
真正的JQuery.ajax传递中文参数的解决方法
May 28 Javascript
玩转JavaScript OOP - 类的实现详解
Jun 08 Javascript
AngularJS基础 ng-non-bindable 指令详细介绍
Aug 02 Javascript
AngularJS实现DOM元素的显示与隐藏功能
Nov 22 Javascript
vue2.0 与 bootstrap datetimepicker的结合使用实例
May 22 Javascript
基于webpack 实用配置方法总结
Sep 28 Javascript
JS和Canvas实现图片的预览压缩和上传功能
Mar 30 Javascript
JS实现中英文混合文字溢出友好截取功能
Aug 06 Javascript
JS栈stack类的实现与使用方法示例
Jan 31 Javascript
原生js实现无缝轮播图效果
Jan 28 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
PHP DataGrid 实现代码
2009/08/12 PHP
php设计模式 Bridge (桥接模式)
2011/06/26 PHP
PHP高自定义性安全验证码代码
2011/11/27 PHP
zend Framework中的Layout(模块化得布局)详解
2013/06/28 PHP
ThinkPHP内置jsonRPC的缺陷分析
2014/12/18 PHP
PHP单例模式数据库连接类与页面静态化实现方法
2019/03/20 PHP
基于laravel belongsTo使用详解
2019/10/18 PHP
javascript[js]获取url参数的代码
2007/10/17 Javascript
js匿名函数的调用示例(形式多种多样)
2014/08/20 Javascript
实例讲解JavaScript的Backbone.js框架中的View视图
2016/05/05 Javascript
使用jQuery Mobile框架开发移动端Web App的入门教程
2016/05/17 Javascript
seaJs使用心得之exports与module.exports的区别实例分析
2017/10/13 Javascript
BootStrap模态框不垂直居中的解决方法
2017/10/19 Javascript
node.js的exports、module.exports与ES6的export、export default深入详解
2017/10/26 Javascript
vue2实现数据请求显示loading图
2017/11/28 Javascript
NodeJS父进程与子进程资源共享原理与实现方法
2018/03/16 NodeJs
详解vue-cli 本地开发mock数据使用方法
2018/05/29 Javascript
vue项目中mock.js的使用及基本用法
2019/05/22 Javascript
Electron vue的使用教程图文详解
2019/07/05 Javascript
layer.confirm()右边按钮实现href的例子
2019/09/27 Javascript
JavaScript中EventBus实现对象之间通信
2020/10/18 Javascript
Python3 适合初学者学习的银行账户登录系统实例
2017/08/08 Python
django 修改server端口号的方法
2018/05/14 Python
浅谈python 中类属性共享的问题
2019/07/02 Python
解决Python3 抓取微信账单信息问题
2019/07/19 Python
python PyAutoGUI 模拟鼠标键盘操作和截屏功能
2019/08/04 Python
西班牙英格列斯百货英国官网:El Corte Inglés英国
2017/10/30 全球购物
List, Set, Map是否继承自Collection接口?
2016/05/16 面试题
自主招生自荐信指南
2014/02/04 职场文书
2014年社区学雷锋活动总结
2014/03/09 职场文书
节能标语大全
2014/06/21 职场文书
夫妻婚内购房协议书
2014/10/05 职场文书
迎新生晚会主持词
2015/06/30 职场文书
工作简报怎么写
2015/07/21 职场文书
nginx location优先级的深入讲解
2021/03/31 Servers
Python学习开发之图形用户界面详解
2021/08/23 Python