JavaScript

超轻量级php框架startmvc

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

更新时间:2020-04-27 12:25:01 作者:startmvc
一、前言  三年.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图片上传、压缩及拍照旋转的问题处理,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!

vue 组件开发 h5 vue 拍照上传