欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

vuejs开发组件分享之H5图片上传、压缩及拍照旋转的问题处理

程序员文章站 2022-06-20 20:38:06
一、前言   三年.net开发转前端已经四个月了,前端主要用webpack+vue,由于后端转过来的,前端不够系统,希望分享下开发心得与园友一起学习。   图片的上传之...

一、前言

  三年.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图片上传、压缩及拍照旋转的问题处理,希望对大家有所帮助