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 清空form表单中某种元素的值
Dec 26 Javascript
js 复制或插入Html的实现方法小结
May 19 Javascript
杨氏矩阵查找的JS代码
Mar 21 Javascript
javascript判断机器是否联网的2种方法
Aug 09 Javascript
javascript检测是否联网的实现代码
Sep 28 Javascript
js实现精美的银灰色竖排折叠菜单
May 16 Javascript
JavaScript获取两个数组交集的方法
Jun 09 Javascript
基于socket.io+express实现多房间聊天
Mar 17 Javascript
javascript 判断是否是微信浏览器的方法
Oct 09 Javascript
js中小数向上取整数,向下取整数,四舍五入取整数的实现(必看篇)
Feb 13 Javascript
Three.js实现绘制字体模型示例代码
Sep 26 Javascript
JS判断数组里是否有重复元素的方法小结
May 21 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 多维数组排序实现代码
2009/08/05 PHP
PHP cdata 处理(详细介绍)
2013/07/05 PHP
php查找任何页面上的所有链接的方法
2013/12/03 PHP
Yii CFileCache 获取不到值的原因分析
2017/02/08 PHP
JS中字符问题(二进制/十进制/十六进制及ASCII码之间的转换)
2008/11/03 Javascript
jQuery 隔行换色 支持键盘上下键,按Enter选定值
2009/08/02 Javascript
javascript中的107个基础知识收集整理 推荐
2010/03/29 Javascript
js利用与或运算符优先级实现if else条件判断表达式
2010/04/15 Javascript
用js的for循环获取radio选中的值
2013/10/21 Javascript
浅析XMLHttpRequest的缓存问题
2013/12/13 Javascript
jquery获取URL中参数解决中文乱码问题的两种方法
2013/12/18 Javascript
JavaScript中创建对象和继承示例解读
2014/02/12 Javascript
jQuery实现的进度条效果
2015/07/15 Javascript
jQuery1.9.1源码分析系列(十六)ajax之ajax框架
2015/12/04 Javascript
Vue 2.0+Vue-router构建一个简单的单页应用(附源码)
2017/03/14 Javascript
webpack配置之后端渲染详解
2017/10/26 Javascript
[07:12]2014DOTA2西雅图国际邀请赛 黑马Liquid专题采访
2014/07/12 DOTA
[53:10]Secret vs Pain 2018国际邀请赛小组赛BO2 第一场 8.17
2018/08/20 DOTA
Python简单实现自动删除目录下空文件夹的方法
2017/08/29 Python
python删除字符串中指定字符的方法
2018/08/13 Python
python的依赖管理的实现
2019/05/14 Python
学习python分支结构
2019/05/17 Python
Python实现的对一个数进行因式分解操作示例
2019/06/27 Python
Flask框架实现的前端RSA加密与后端Python解密功能详解
2019/08/13 Python
python实现大量图片重命名
2020/03/23 Python
Python实现仿射密码的思路详解
2020/04/23 Python
2020年10款优秀的Python第三方库,看看有你中意的吗?
2021/01/12 Python
使用css3制作登录表单的步骤
2014/04/07 HTML / CSS
英国泰坦旅游网站:全球陪同游览,邮轮和铁路旅行
2016/11/29 全球购物
美国高端医师级美容产品电商:BeautifiedYou.com
2017/04/17 全球购物
美国马匹用品和骑马配件购物网站:Horse.com
2018/01/08 全球购物
迪奥美国官网:Dior美国
2019/12/07 全球购物
ASP.NET中的身份验证有那些
2012/07/13 面试题
无工作经验者个人求职信范文
2013/12/22 职场文书
《唯一的听众》教学反思
2016/02/18 职场文书
使用CSS自定义属性实现骨架屏效果
2022/06/21 HTML / CSS