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
IE6下javasc#ipt:void(0) 无效的解决方法
Dec 23 Javascript
JavaScript四种调用模式和this示例介绍
Jan 02 Javascript
Javascript 函数parseInt()转换时出现bug问题
May 20 Javascript
javascript中createElement的两种创建方式
May 14 Javascript
简介JavaScript中toUpperCase()方法的使用
Jun 06 Javascript
利用JS实现数字增长
Jul 28 Javascript
微信小程序 引用其他js文件实现代码
Feb 22 Javascript
JavaScript简单计算人的年龄示例
Apr 15 Javascript
详解vue 组件之间使用eventbus传值
Oct 25 Javascript
JavaScript登录验证基础教程
Nov 01 Javascript
vue2 前端搜索实现示例
Feb 26 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
PHP4实际应用经验篇(6)
2006/10/09 PHP
php判断电脑访问、手机访问的例子
2014/05/10 PHP
thinkphp四种url访问方式详解
2014/11/28 PHP
php从csv文件读取数据并输出到网页的方法
2015/03/14 PHP
thinkphp如何获取客户端IP
2015/11/03 PHP
PHP中使用array函数新建一个数组
2015/11/19 PHP
Yii2框架RESTful API 格式化响应,授权认证和速率限制三部分详解
2016/11/10 PHP
PHP Swoole异步MySQL客户端实现方法示例
2019/10/24 PHP
jquery iframe操作详细解析
2013/11/20 Javascript
IE与FireFox的JavaScript兼容问题解决办法
2013/12/31 Javascript
js判断登陆用户名及密码是否为空的简单实例
2016/05/16 Javascript
AngularJS延迟加载html template
2016/07/27 Javascript
获取select的value、text值的简单示例(jquery与javascript)
2016/12/07 Javascript
JS利用cookies设置每隔24小时弹出框
2017/04/20 Javascript
AngularJs每天学习之总体介绍
2017/08/07 Javascript
vue data恢复初始化数据的实现方法
2019/10/31 Javascript
使用Vue.set()方法实现响应式修改数组数据步骤
2019/11/09 Javascript
Python 字符串大小写转换的简单实例
2017/01/21 Python
python matplotlib坐标轴设置的方法
2017/12/05 Python
python matplotlib 注释文本箭头简单代码示例
2018/01/08 Python
python逆向入门教程
2018/01/15 Python
Python判断两个list是否是父子集关系的实例
2018/05/04 Python
Python创建普通菜单示例【基于win32ui模块】
2018/05/09 Python
浅谈Tensorflow由于版本问题出现的几种错误及解决方法
2018/06/13 Python
PyCharm搭建Spark开发环境实现第一个pyspark程序
2019/06/13 Python
pyqt 实现为长内容添加滑轮 scrollArea
2019/06/19 Python
解决Numpy中sum函数求和结果维度的问题
2019/12/06 Python
python 解决selenium 中的 .clear()方法失效问题
2020/09/01 Python
HTML5实现移动端点击翻牌功能
2020/10/23 HTML / CSS
Expedia加拿大官方网站:加拿大最大的在线旅游提供商
2017/12/31 全球购物
C/C++有关内存的思考题
2015/12/04 面试题
.NET笔试题(20个问题)
2016/02/02 面试题
学年末自我鉴定
2014/01/21 职场文书
沈阳故宫导游词
2015/01/31 职场文书
分位数回归模型quantile regeression应用详解及示例教程
2021/11/02 Python
Spring this调用当前类方法无法拦截的示例代码
2022/03/20 Java/Android