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 相关文章推荐
JavaScript 事件参考手册
Dec 24 Javascript
JS中图片缓冲loading技术的实例代码
Aug 29 Javascript
jQuery实现平滑滚动页面到指定锚点链接的方法
Jul 15 Javascript
AngularJS中$http服务常用的应用及参数
Aug 22 Javascript
浅谈javascript中的数据类型转换
Dec 27 Javascript
浅析vue component 组件使用
Mar 06 Javascript
AngularJS日程表案例详解
Aug 15 Javascript
JS继承与闭包及JS实现继承的三种方式
Oct 15 Javascript
webpack 静态资源集中输出的方法示例
Nov 09 Javascript
ES6中Symbol、Set和Map用法详解
Aug 20 Javascript
JS绘图Flot应用图形绘制异常解决方案
Oct 16 Javascript
vue-axios同时请求多个接口 等所有接口全部加载完成再处理操作
Nov 09 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 syntax error, unexpected $end 错误的一种原因及解决
2008/10/25 PHP
简单的php文件上传(实例)
2013/10/27 PHP
thinkphp如何获取客户端IP
2015/11/03 PHP
thinkPHP微信分享接口JSSDK用法实例
2017/07/07 PHP
PHP中十六进制颜色与RGB颜色值互转的方法
2019/03/18 PHP
js数组中如何随机取出一个值
2014/06/13 Javascript
jQuery实现带延迟的二级tab切换下拉列表效果
2015/09/01 Javascript
jQuery基于$.ajax设置移动端click超时处理方法
2016/05/14 Javascript
jQuery控制控件文本的长度的操作方法
2016/12/05 Javascript
JavaScript实现二分查找实例代码
2017/02/22 Javascript
vue-cli结合Element-ui基于cropper.js封装vue实现图片裁剪组件功能
2018/03/01 Javascript
利用nodeJs anywhere搭建本地服务器环境的方法
2018/05/12 NodeJs
JavaScript设计模式之责任链模式实例分析
2019/01/16 Javascript
总结4个方面优化Vue项目
2019/02/11 Javascript
详解javascript replace高级用法
2019/02/17 Javascript
3分钟了解vue数据劫持的原理实现
2019/05/01 Javascript
js实现一个简易计算器
2020/03/30 Javascript
详解微信小程序入门从这里出发(登录注册、开发工具、文件及结构介绍)
2020/07/21 Javascript
[03:37]2015国际邀请赛第四日现场精彩集锦
2015/08/08 DOTA
Python写的Tkinter程序屏幕居中方法
2015/03/10 Python
Python编程中运用闭包时所需要注意的一些地方
2015/05/02 Python
图文详解WinPE下安装Python
2016/05/17 Python
Python如何生成树形图案
2018/01/03 Python
python搭建服务器实现两个Android客户端间收发消息
2018/04/12 Python
python跳出双层for循环的解决方法
2019/06/24 Python
Django 响应数据response的返回源码详解
2019/08/06 Python
pandas 缺失值与空值处理的实现方法
2019/10/12 Python
关于PyCharm安装后修改路径名称使其可重新打开的问题
2020/10/20 Python
Kathmandu澳洲户外商店:新西兰户外运动品牌
2017/11/12 全球购物
小学英语教学反思案例
2014/02/04 职场文书
证券区域经理岗位职责
2015/04/10 职场文书
入党介绍人考察意见
2015/06/01 职场文书
辞职信怎么写?你都知道吗?
2019/06/24 职场文书
使用Python解决图表与画布的间距问题
2022/04/11 Python
mysql 体系结构和存储引擎介绍
2022/05/06 MySQL
mybatis 获取更新记录的id
2022/05/20 Java/Android