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与webservice的通信实现代码
Dec 25 Javascript
javascript时间函数基础介绍
Mar 28 Javascript
JavaScript的21条基本知识点
Mar 04 Javascript
js实现横向百叶窗效果网页切换动画效果的方法
Mar 02 Javascript
JavaScript中的fontsize()方法使用详解
Jun 08 Javascript
JS拖拽插件实现步骤
Aug 03 Javascript
使用coffeescript编写node.js项目的方法汇总
Aug 05 Javascript
jQuery特殊符号转义的实现
Nov 30 Javascript
node.js文件上传重命名以及移动位置的示例代码
Jan 19 Javascript
vue 组件 全局注册和局部注册的实现
Feb 28 Javascript
Vue-router 切换组件页面时进入进出动画方法
Sep 01 Javascript
JavaScript实现省市区三级联动
Feb 13 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
中国广播史趣谈 — 几个历史第一次
2021/03/01 无线电
基于php中echo用逗号和用点号的区别详解
2018/01/23 PHP
JS URL传中文参数引发的乱码问题
2009/09/02 Javascript
jquery实现的超出屏幕时把固定层变为定位层的代码
2010/02/23 Javascript
读jQuery之四(优雅的迭代)
2011/06/20 Javascript
JS判断不同分辨率调用不同的CSS样式文件实现思路及测试代码
2013/01/23 Javascript
Jquery选择器中使用变量实现动态选择例子
2014/07/25 Javascript
基于zepto.js简单实现上传图片
2016/06/21 Javascript
BootStrap轮播HTML代码(推荐)
2016/12/10 Javascript
vue-dialog的弹出层组件
2020/05/25 Javascript
Vue.js仿微信聊天窗口展示组件功能
2017/08/11 Javascript
vue路由跳转时判断用户是否登录功能的实现
2017/10/26 Javascript
Vue 按键修饰符处理事件的方法
2018/05/04 Javascript
Vue 中使用富文本编译器wangEditor3的方法
2019/09/26 Javascript
20多个小事例带你重温ES10新特性(小结)
2019/09/29 Javascript
js实现盒子移动动画效果
2020/08/09 Javascript
[03:15]DOTA2-DPC中国联赛1月22日Recap集锦
2021/03/11 DOTA
python简单判断序列是否为空的方法
2015/06/30 Python
Python多线程、异步+多进程爬虫实现代码
2016/02/17 Python
python3制作捧腹网段子页爬虫
2017/02/12 Python
Python学习小技巧之列表项的推导式与过滤操作
2017/05/20 Python
Python抓取框架Scrapy爬虫入门:页面提取
2017/12/01 Python
python 日期操作类代码
2018/05/05 Python
Python中循环后使用list.append()数据被覆盖问题的解决
2018/07/01 Python
python实现回旋矩阵方式(旋转矩阵)
2019/12/04 Python
基于Tensorflow的MNIST手写数字识别分类
2020/06/17 Python
以工厂直接定价的传奇性能:Ben Hogan Golf
2019/01/04 全球购物
信息专业学生学习的自我评价
2014/02/17 职场文书
售前工程师职业生涯规划
2014/03/02 职场文书
2014教育局对照检查材料思想汇报
2014/09/23 职场文书
汽车销售助理岗位职责
2015/04/14 职场文书
给校长的建议书作文300字
2015/09/14 职场文书
2016年秋季运动会通讯稿
2015/11/25 职场文书
毕业生的自我鉴定表范文
2019/05/16 职场文书
多人盗宝《绿林侠盗》第三赛季4.5上线 跨平台实装
2022/04/03 其他游戏
JS实现简单的九宫格抽奖
2022/06/28 Javascript