vuejs开发组件分享之H5图片上传、压缩及拍照旋转的问题处理


Posted in Javascript onMarch 06, 2017

一、前言

三年.net开发转前端已经四个月了,前端主要用webpack+vue,由于后端转过来的,前端不够系统,希望分享下开发心得与园友一起学习。

图片的上传之前都是用的插件(ajaxupload),或者传统上传图片的方式,各有利弊:插件的问题是依赖jq并且会使系统比较臃肿,还有传统的web开发模式 前后端偶尔在一起及对用户体验要求低,现在公司采用webpack+vue+restfullApi开发模式 前后端完全分离,遵从高内聚,低偶尔的原则,开发人员各司其职,一则提升开发效率(从长期来看,短期对于很多开发人员需要有个适应的过程,特别是初中级的前端处理业务逻辑方面的能力比较欠缺),二则提升用户体验。今天分享下在项目开发中写的的图片上传 vue组件。

二、处理问题

这里用h5做图片上传考虑到浏览器支持的问题,这里考虑的场景是在做webapp的时候

1.移动web图片上传还包括拍摄上传,但是在移动端会出现拍摄的照片会旋转,处理这个问题需要得到图片旋转的情况,可以用exif.js来获取,具体可以参看文档

2.图片压缩

3.旋转

三、代码

1组件代码

<template>
 <div>
  <input type="file" style="display: none;" id="img-upload" multiple accept="image/*" @change="uploadImg($event)"/>
 </div>
</template>
<script>
 import EXIF from '../../../Resource/Global/Js/exif'
 export default{
  name:"image-html5-upload",
  props:{
   imgArr:{
    type:Array,
    twoWay: true,
    default:Array
   },
   imgNumLimit:{//一次最多可以上传多少张照片
    type:Number,
    default:4
   }
  },
  methods:{
   "uploadImg": function(e){
    let tag = e.target;
    let fileList = tag.files;
    let imgNum = fileList.length;
    let _this = this;
    _this.imgArr = [];//图片数据清零
    if(this.imgArr.length + imgNum > this.imgNumLimit){
     alert('一次最多上传'+this.imgNumLimit+'张图片!');
     return;
    }
    var Orientation;
    for(let i=0;i<imgNum;i++){
     EXIF.getData(fileList[i], function(){
      Orientation = EXIF.getTag(fileList[i], 'Orientation');
     });
     let reader = new FileReader();
     reader.readAsDataURL(fileList[i]);
     reader.onload = function(){
      var oReader = new FileReader();
      oReader.onload = function(e) {
       var image = new Image();
       image.src = e.target.result;
       image.onload = function() {
        var expectWidth = this.naturalWidth;
        var expectHeight = this.naturalHeight;
        if (this.naturalWidth > this.naturalHeight && this.naturalWidth > 800) {
         expectWidth = 800;
         expectHeight = expectWidth * this.naturalHeight / this.naturalWidth;
        } else if (this.naturalHeight > this.naturalWidth && this.naturalHeight > 1200) {
         expectHeight = 1200;
         expectWidth = expectHeight * this.naturalWidth / this.naturalHeight;
        }
        var canvas = document.createElement("canvas");
        var ctx = canvas.getContext("2d");
        canvas.width = expectWidth;
        canvas.height = expectHeight;
        ctx.drawImage(this, 0, 0, expectWidth, expectHeight);
        var base64 = null;
        //修复ios上传图片的时候 被旋转的问题
        if(Orientation != "" && Orientation != 1){
         switch(Orientation){
          case 6://需要顺时针(向左)90度旋转
           _this.rotateImg(this,'left',canvas);
           break;
          case 8://需要逆时针(向右)90度旋转
           _this.rotateImg(this,'right',canvas);
           break;
          case 3://需要180度旋转
           _this.rotateImg(this,'right',canvas);//转两次
           _this.rotateImg(this,'right',canvas);
           break;
         }
        }
        base64 = canvas.toDataURL("image/jpeg", 0.8);
        if(fileList[i].size / 1024000 > 1){
         _this.imgScale(base64, 4)
        }else{
         _this.imgArr.push({"src": base64});
        }
        console.log(JSON.stringify(_this.imgArr));
       };
      };
      oReader.readAsDataURL(fileList[i]);
     }
    }
   },
   "imgScale": function(imgUrl,quality){
    let img = new Image();
    let _this = this;
    let canvas = document.createElement('canvas');
    let cxt = canvas.getContext('2d');
    img.src = imgUrl;
    img.onload = function(){
     //缩放后图片的宽高
     let width = img.naturalWidth/quality;
     let height = img.naturalHeight/quality;
     canvas.width = width;
     canvas.height = height;
     cxt.drawImage(this, 0, 0, width, height);
     _this.imgArr.push({"src": canvas.toDataURL('image/jpeg')});
    }
   },
   "rotateImg":function (img, direction,canvas) {//图片旋转
    var min_step = 0;
    var max_step = 3;
    if (img == null)return;
    var height = img.height;
    var width = img.width;
    var step = 2;
    if (step == null) {
     step = min_step;
    }
    if (direction == 'right') {
     step++;
     step > max_step && (step = min_step);
    } else {
     step--;
     step < min_step && (step = max_step);
    }
    var degree = step * 90 * Math.PI / 180;
    var ctx = canvas.getContext('2d');
    switch (step) {
     case 0:
      canvas.width = width;
      canvas.height = height;
      ctx.drawImage(img, 0, 0);
      break;
     case 1:
      canvas.width = height;
      canvas.height = width;
      ctx.rotate(degree);
      ctx.drawImage(img, 0, -height);
      break;
     case 2:
      canvas.width = width;
      canvas.height = height;
      ctx.rotate(degree);
      ctx.drawImage(img, -width, -height);
      break;
     case 3:
      canvas.width = height;
      canvas.height = width;
      ctx.rotate(degree);
      ctx.drawImage(img, -width, 0);
      break;
    }
   }
  }
 }
</script>

2.使用方法

<template>
 <div>
  <div class="album-img-list">
   <ul>
    <li v-for="img in imgList"><div class="album-bg-img"><img :src='img.src'> </div></li>
   </ul>
  </div>
  <div class="album">
   <label for="img-upload">上传照片</label>
    <image-html5-upload :img-arr.sync="imgList"></image-html5-upload>
  </div>
 </div>
</template>

以上所述是小编给大家介绍的vuejs开发组件分享之H5图片上传、压缩及拍照旋转的问题处理,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
基于Jquery的文字滚动跑马灯插件(一个页面多个滚动区)
Jul 26 Javascript
jQuery的cookie插件实现保存用户登陆信息
Apr 15 Javascript
html的DOM中Event对象onabort事件用法实例
Jan 21 Javascript
JQuery菜单效果的两个实例讲解(3)
Sep 17 Javascript
JS获取年月日时分秒的方法分析
Nov 28 Javascript
js实现键盘自动打字效果
Dec 23 Javascript
js编写简单的聊天室功能
Aug 17 Javascript
JavaScript中Hoisting详解 (变量提升与函数声明提升)
Aug 18 Javascript
开发Vue树形组件的示例代码
Dec 21 Javascript
Vue异步组件处理路由组件加载状态的解决方案
Sep 07 Javascript
vue配置font-awesome5的方法步骤
Jan 27 Javascript
微信二次分享报错invalid signature问题及解决方法
Apr 01 Javascript
js正则表达式验证表单【完整版】
Mar 06 #Javascript
Vue.js 2.0 移动端拍照压缩图片上传预览功能
Mar 06 #Javascript
js实现动态显示时间效果
Mar 06 #Javascript
jQuery实现 上升、下降、删除、添加一行代码
Mar 06 #Javascript
Node.js使用NodeMailer发送邮件实例代码
Mar 06 #Javascript
js eval函数使用,js对象和字符串互转实例
Mar 06 #Javascript
js实现4个方向滚动的球
Mar 06 #Javascript
You might like
PHP 类型转换函数intval
2009/06/20 PHP
检测png图片是否完整的php代码
2010/09/06 PHP
PHP遍历文件夹与文件类及处理类用法实例
2014/09/23 PHP
thinkPHP框架自动填充原理与用法分析
2018/04/03 PHP
php连接mysql数据库最简单的实现方法
2019/09/24 PHP
js replace正则表达式应用案例讲解
2013/01/17 Javascript
ajax处理php返回json数据的实例代码
2013/01/24 Javascript
JS实现标签页效果(配合css)
2013/04/03 Javascript
jQuery类选择器用法实例
2014/12/23 Javascript
深入理解JavaScript系列(28):设计模式之工厂模式详解
2015/03/03 Javascript
jQuery on()方法示例及jquery on()方法的优点
2015/08/27 Javascript
Bootstrap每天必学之js插件
2015/11/30 Javascript
简单总结JavaScript中的String字符串类型
2016/05/26 Javascript
JS控制文本域只读或可写属性的方法
2016/06/24 Javascript
JavaScript实现打地鼠小游戏
2020/04/23 Javascript
angular使用post、get向后台传参的问题实例
2017/05/27 Javascript
js轮播图的插件化封装详解
2017/07/17 Javascript
使用Vue中 v-for循环列表控制按钮隐藏显示功能
2019/04/23 Javascript
Vue之beforeEach非登录不能访问的实现(代码亲测)
2019/07/18 Javascript
node.js实现简单的压缩/解压缩功能示例
2019/11/05 Javascript
vue 监听 Treeselect 选择项的改变操作
2020/08/31 Javascript
[02:28]DOTA2 2017国际邀请赛小组赛回顾
2017/08/09 DOTA
Python对小数进行除法运算的正确方法示例
2014/08/25 Python
python设计模式大全
2016/06/27 Python
Python正则表达式匹配日期与时间的方法
2019/07/07 Python
Django连接数据库并实现读写分离过程解析
2019/11/13 Python
Django对接支付宝实现支付宝充值金币功能示例
2019/12/17 Python
python查找特定名称文件并按序号、文件名分行打印输出的方法
2020/04/24 Python
Python实现加密的RAR文件解压的方法(密码已知)
2020/09/11 Python
Autopep8的使用(python自动编排工具)
2021/03/02 Python
HTML5在a标签内放置块级元素示例代码
2013/08/23 HTML / CSS
应用心理学个人的求职信
2013/12/08 职场文书
争论的故事教学反思
2014/02/06 职场文书
五心教育心得体会
2014/09/04 职场文书
校园安全广播稿范文
2014/09/25 职场文书
Redis超详细讲解高可用主从复制基础与哨兵模式方案
2022/04/07 Redis