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 树形导航菜单实例代码
Aug 13 Javascript
Jquery读取URL参数小例子
Aug 30 Javascript
特殊情况下如何获取span里面的值
May 20 Javascript
JavaScript中变量声明有var和没var的区别示例介绍
Sep 15 Javascript
给before和after伪元素设置js效果的方法
Dec 04 Javascript
基于jquery编写的放大镜插件
Mar 23 Javascript
JavaScript中子对象访问父对象的方式详解
Sep 01 Javascript
jquery实现焦点轮播效果
Feb 23 Javascript
对angularjs框架下controller间的传值方法详解
Oct 08 Javascript
js实现一个简易计算器
Mar 30 Javascript
JavaScript实现烟花绽放动画效果
Aug 04 Javascript
解决antd Form 表单校验方法无响应的问题
Oct 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
PHP中strnatcmp()函数“自然排序算法”进行字符串比较用法分析(对比strcmp函数)
2016/01/07 PHP
PHP设计模式之工厂模式详解
2017/10/24 PHP
PHP 7.4 新语法之箭头函数实例详解
2019/05/09 PHP
通过PHP实现获取访问用户IP
2020/05/09 PHP
设为首页和收藏的Javascript代码(亲测兼容IE,Firefox,chrome等浏览器)
2013/11/18 Javascript
jQuery设置与获取HTML,文本和值的简单实例
2014/02/26 Javascript
js动态往表格的td中添加图片并注册事件
2014/06/12 Javascript
JavaScript Math.ceil 方法(对数值向上取整)
2015/01/09 Javascript
jQuery实现文件上传进度条特效
2015/08/12 Javascript
javascript求日期差的方法
2016/03/02 Javascript
封装的dialog插件 基于bootstrap模态对话框的简单扩展
2016/08/10 Javascript
将html页面保存成图片,图片写入pdf的实现方法(推荐)
2016/09/17 Javascript
getElementById().innerHTML与getElementById().value的区别
2016/10/27 Javascript
DropDownList实现可输入可选择(两种版本可选)
2016/12/07 Javascript
JS简单实现表格排序功能示例
2016/12/20 Javascript
IntersectionObserver实现图片懒加载的示例
2017/09/29 Javascript
vue的diff算法知识点总结
2018/03/29 Javascript
angular学习之动态创建表单的方法
2018/12/07 Javascript
Jquery获取radio选中值实例总结
2019/01/17 jQuery
京东优选小程序的实现代码示例
2020/02/25 Javascript
关于element的表单组件整理笔记
2021/02/05 Javascript
python计算圆周率pi的方法
2015/07/11 Python
python使用正则表达式匹配字符串开头并打印示例
2017/01/11 Python
Windows 64位下python3安装nltk模块
2018/09/19 Python
python os模块简单应用示例
2019/05/23 Python
Django 自定义分页器的实现代码
2019/11/24 Python
python scatter函数用法实例详解
2020/02/11 Python
pycharm下pyqt4安装及环境配置的教程
2020/04/24 Python
详解python方法之绑定方法与非绑定方法
2020/08/17 Python
Css3圆角边框制作代码
2015/11/18 HTML / CSS
CSS3点击按钮实现背景渐变动画效果
2016/10/19 HTML / CSS
学校党员个人问题整改措施思想汇报
2014/10/08 职场文书
法定代表人授权委托书格式
2014/10/14 职场文书
护士实习自荐信
2015/03/06 职场文书
法定代表人免职证明
2015/06/24 职场文书
运动会100米广播稿
2015/08/19 职场文书