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 相关文章推荐
tagName的使用,留一笔
Jun 26 Javascript
Confirmer JQuery确认对话框组件
Jun 09 Javascript
JavaScript中创建类/对象的几种方法总结
Nov 29 Javascript
遍历DOM对象内的元素属性示例代码
Feb 08 Javascript
一个很有趣3D球状标签云兼容IE8
Aug 22 Javascript
原生javaScript实现图片延时加载的方法
Dec 22 Javascript
jQuery中Ajax的load方法详解
Jan 14 Javascript
js判断浏览器类型及设备(移动页面开发)
Jul 30 Javascript
分享一个插件实现水珠自动下落效果
Jun 01 Javascript
js创建数组的简单方法
Jul 27 Javascript
jQuery实现的页面遮罩层功能示例【测试可用】
Oct 14 jQuery
解决vue中的无限循环问题
Jul 27 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
vBulletin HACK----显示话题大小和打开新窗口于论坛索引页
2006/10/09 PHP
PHP时间戳使用实例代码
2008/06/07 PHP
PHP中Session和Cookie是如何操作的
2015/10/10 PHP
详解WordPress中过滤链接与过滤SQL语句的方法
2015/12/18 PHP
js 替换
2008/02/19 Javascript
7款吸引人眼球的jQuery/CSS3特效实例分享
2013/04/25 Javascript
jQuery阻止事件冒泡具体实现
2013/10/11 Javascript
jQuery中[attribute*=value]选择器用法实例
2014/12/31 Javascript
JQuery显示隐藏DIV的方法及代码实例
2015/04/16 Javascript
JS版元素周期表实现方法
2015/08/05 Javascript
jQuery中的deferred使用方法
2017/03/27 jQuery
angular 用拦截器统一处理http请求和响应的方法
2017/06/08 Javascript
express框架实现基于Websocket建立的简易聊天室
2017/08/10 Javascript
vue router自动判断左右翻页转场动画效果
2017/10/10 Javascript
详解React-Native全球化多语言切换工具库react-native-i18n
2017/11/03 Javascript
fullpage.js最后一屏滚动方式
2018/02/06 Javascript
koa+jwt实现token验证与刷新功能
2019/05/30 Javascript
微信小程序实用代码段(收藏版)
2019/12/17 Javascript
Element InputNumber 计数器的实现示例
2020/08/03 Javascript
python统计字符串中指定字符出现次数的方法
2015/04/04 Python
python if not in 多条件判断代码
2016/09/21 Python
python中类和实例如何绑定属性与方法示例详解
2017/08/18 Python
Python中的Django基本命令实例详解
2018/07/15 Python
利用python在大量数据文件下删除某一行的例子
2019/08/21 Python
python实现的接收邮件功能示例【基于网易POP3服务器】
2019/09/11 Python
Python jieba库用法及实例解析
2019/11/04 Python
python socket通信编程实现文件上传代码实例
2019/12/14 Python
Django的ListView超详细用法(含分页paginate)
2020/05/21 Python
Python爬虫基于lxml解决数据编码乱码问题
2020/07/31 Python
HTML5事件方法全部汇总
2016/05/12 HTML / CSS
租租车:国际租车、美国租车、欧洲租车、特价预订国外租车(中文服务)
2018/03/28 全球购物
美赞臣新加坡官方旗舰店:Enfagrow新加坡
2019/05/15 全球购物
日本最大的购物网站乐天市场国际版:Rakuten Global Market(支持中文)
2020/02/03 全球购物
销售团队口号大全
2014/06/06 职场文书
党员四风问题对照检查材料思想汇报
2014/09/16 职场文书
MySQL慢查询优化解决问题
2022/03/17 MySQL