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 相关文章推荐
线路分流自动跳转代码;希望对大家有用!
Dec 02 Javascript
解决AJAX中跨域访问出现'没有权限'的错误
Aug 20 Javascript
javascript 折半查找字符在数组中的位置(有序列表)
Dec 09 Javascript
Javascript继承(上)——对象构建介绍
Nov 08 Javascript
javascript修改表格背景色实例代码分享
Dec 10 Javascript
jquery无法设置checkbox选中即没有变成选中状态
Mar 27 Javascript
如何利用AngularJS打造一款简单Web应用
Dec 05 Javascript
详解使用grunt完成requirejs的合并压缩和js文件的版本控制
Mar 02 Javascript
原生JavaScript实现的简单省市县三级联动功能示例
May 27 Javascript
关于Angular2 + node接口调试的解决方案
May 28 Javascript
微信小程序五子棋游戏的悔棋实现方法【附demo源码下载】
Feb 20 Javascript
详解key在Vue列表渲染时究竟起到了什么作用
Apr 20 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字符串的比较函数strcmp()与strcasecmp()的使用详解
2013/05/15 PHP
PHP扩展模块memcached长连接使用方法分析
2014/12/24 PHP
php中通过DirectoryIterator删除整个目录的方法
2015/03/13 PHP
php字符串比较函数用法小结(strcmp,strcasecmp,strnatcmp及strnatcasecmp)
2016/07/18 PHP
地址栏上的一段语句,改变页面的风格。(教程)
2008/04/02 Javascript
基于jquery的cookie的用法
2011/01/10 Javascript
如何从jQuery的ajax请求中删除X-Requested-With
2013/12/11 Javascript
jquery自适应布局的简单实例
2016/05/28 Javascript
浅谈jQuery 中的事件冒泡和阻止默认行为
2016/05/28 Javascript
Node.js中常规的文件操作总结
2016/10/13 Javascript
Javascript 实现全屏滚动实例代码
2016/12/31 Javascript
基于vue2框架的机器人自动回复mini-project实例代码
2017/06/13 Javascript
[js高手之路]图解javascript的原型(prototype)对象,原型链实例
2017/08/28 Javascript
node.js用fs.rename强制重命名或移动文件夹的方法
2017/12/27 Javascript
详解Vue.js使用Swiper.js在iOS
2018/09/10 Javascript
JavaScript 自定义html元素鼠标右键菜单功能
2019/12/02 Javascript
JS实现网页时钟特效
2020/03/25 Javascript
ant design pro中可控的筛选和排序实例
2020/11/17 Javascript
[20:39]DOTA2-DPC中国联赛 正赛开幕式 1月18日
2021/03/11 DOTA
Python绘制3d螺旋曲线图实例代码
2017/12/20 Python
Python 实现「食行生鲜」签到领积分功能
2018/09/26 Python
基于Python实现迪杰斯特拉和弗洛伊德算法
2020/05/27 Python
Python之lambda匿名函数及map和filter的用法
2019/03/05 Python
利用rest framework搭建Django API过程解析
2019/08/31 Python
Python PyPDF2模块安装使用解析
2020/01/19 Python
python 实现批量图片识别并翻译
2020/11/02 Python
解决pycharm导入numpy包的和使用时报错:RuntimeError: The current Numpy installation (‘D:\\python3.6\\lib\\site-packa的问题
2020/12/08 Python
Bally美国官网:经典瑞士鞋履、手袋及配饰奢侈品牌
2018/05/18 全球购物
美国尼曼百货官网:Neiman Marcus
2019/09/05 全球购物
奥地利婴儿用品和玩具购物网站:baby-markt.at
2020/01/26 全球购物
SQL中where和having的区别
2012/06/17 面试题
介绍一下Linux中的链接
2016/06/05 面试题
表彰先进的通报
2014/01/31 职场文书
2014年团支部工作总结
2014/11/17 职场文书
离退休人员聘用协议书
2014/11/24 职场文书
神秘岛读书笔记
2015/07/01 职场文书