解决uniapp在h5图片上传后旋转90度问题(editor同样适用)

问题简单描述

以往没有uniapp上传图片的经验,这两天刚接手这个功能,遇到了一系列糟心的事情

1.第一版我使用的插件市场的图片压缩插件,出现的问题:低版本安卓拍照出现闪退白屏等问题

2.第二版我换了个图片压缩插件,出现的问题:
a:上传成功后,提交数据,结果在iOS上不能调用window.webkit关闭当前网页,于是只好ISO做了拦截处理,这不是最严重的,最严重的是
b:图片上传成功后逆时针旋转了90度

解决办法

我也百度参考以往大佬的经验,最后终于完美解决了:
1.导入exif插件
import EXIF from ‘@/utils/exif.js’

2.uni.chooseImage选择上传图片,获取到res后的blod

data() {
		return {
			maxSize:10,
			resImg:''
		}
	},
methods: {	
insertImage() {
		uni.chooseImage({
			count: 1,
			size:10*1000000,
			sizeType: ['compressed'],
			success: (res) => {
				//这是需求要求的上传限制,可以不要
				if (parseInt(tempFiles.size) > this.maxSize * 1024 * 1024) {
					uni.showToast({
						title: '图片大于'+this.maxSize+'MB!',
						icon: 'none'
					})
				} else {
					this.resImg = res.tempFilePaths[0]//这就是要的blod
					this.detail(this.resImg)
				}	
			}
		})
	},
}

3.调用this.detail方法做图片处理,这里还用到了this.comprossImage图片压缩和this.getImageTag图片方法,以及最后对图片修正处理方法this.rotateImg,直接粘贴就行

		//url 就是上面获取到的blod
		async detail(url){
	     let maxWidth = 500;  
	     let Orientation = 1;  
	     //获取图片META信息  
	     await this.getImageTag(url, 'Orientation', function(e) {  
	         if(e != undefined) Orientation = e;  
	     })  
	     var img = null;  
	     var canvas = null;  
	     await this.comprossImage(url, maxWidth, function(e) {  
	         img = e.img;  
	         canvas = e.canvas;  
	     })  
	 
	     console.log(Orientation,"Orientation")  
	     let baseStr = '';  
	     //如果方向角不为1,都需要进行旋转  
	     switch(Orientation){  
	         case 6://需要顺时针(向右)90度旋转  
	             baseStr = this.rotateImg(img,'right',canvas);  
	             break;  
	         case 8://需要逆时针(向左)90度旋转   
	             baseStr = this.rotateImg(img,'left',canvas);  
	             break;  
	 
	         case 3://需要180度旋转 转两次  
	             baseStr = this.rotateImg(img,'right',canvas, 2);  
	             break;  
	         default:  
	             baseStr = this.rotateImg(img,'',canvas);  
	             break;  
	     }  
			console.log(baseStr,"baseStr")
			this.uploadImg(baseStr)//图片上传到服务器的方法
	 },
	 
	 //-------------------------------直接粘贴的三个方法
	 	 async comprossImage(imgSrc, maxWidth, func){  
	     if(!imgSrc) return 0;  
	     return new Promise((resolve, reject) => {  
	         uni.getImageInfo({  
	             src: imgSrc,  
	             success(res) {  
	                 let img = new Image();  
	                 img.src = res.path;  
	                 console.log(img)  
	 
	                 let canvas = document.createElement('canvas');  
	 
	                 let obj = new Object();  
	                 obj.img = img;  
	                 obj.canvas = canvas;  
	                 resolve(func(obj));  
	             }  
	         });  
	     })  
	 },
	  /**  
	  * @desc 获取图片信息,使用exif.js库,具体用法请在github中搜索  
	  * @param {Object} file 上传的图片文件  
	  * @param {String} tag 需要获取的信息 例如:'Orientation'旋转信息  
	  * @return {Promise<Any>} 读取是个异步操作,返回指定的图片信息  
	  */  
	getImageTag(file, tag, suc){  
	     if (!file) return 0;  
	     return new Promise((resolve, reject) => {  
	         /* eslint-disable func-names */  
	         // 箭头函数会修改this,所以这里不能用箭头函数  
	         let imgObj = new Image()  
	         imgObj.src = file  
	         console.log(imgObj)  
	         uni.getImageInfo({  
	             src: file,  
	             success(res) {  
	                 EXIF.getData(imgObj, function () {  
	                     EXIF.getAllTags(this);    
	                     let or = EXIF.getTag(this,'Orientation');//这个Orientation 就是我们判断需不需要旋转的值了,有1、3、6、8  
	                     resolve(suc(or))  
	                 });  
	             }  
	         })  
	     });  
	 },
	 	 rotateImg(img, direction, canvas, times = 1){   
	     console.log('开始旋转')  
	     //最小与最大旋转方向,图片旋转4次后回到原方向    
	     var min_step = 0;    
	     var max_step = 3;    
	     if (img == null)return;    
	 
	     //img的高度和宽度不能在img元素隐藏后获取,否则会出错    
	     var height = img.height;    
	     var width = img.width;    
	     let maxWidth = 500;  
	     let canvasWidth = width; //图片原始长宽  
	     let canvasHeight = height;  
	     let base = canvasWidth/canvasHeight;  
	     console.log(maxWidth);  
	     if(canvasWidth > maxWidth){  
	         canvasWidth = maxWidth;  
	         canvasHeight = Math.floor(canvasWidth/base);  
	     }  
	     width = canvasWidth;  
	     height = canvasHeight;  
	     var step = 0;    
	 
	     if (step == null) {    
	       step = min_step;    
	     }    
	 
	     if (direction == 'right') {    
	       step += times;    
	       //旋转到原位置,即超过最大值    
	       step > max_step && (step = min_step);    
	     } else if(direction == 'left'){    
	       step -= times;    
	       step < min_step && (step = max_step);    
	     } else {    //不旋转  
	         step = 0;  
	     }  
	 
	     //旋转角度以弧度值为参数    
	     var degree = step * 90 * Math.PI / 180;    
	     var ctx = canvas.getContext('2d');    
	     console.log(degree)  
	     console.log(step)  
	     switch (step) {      
	       case 1:    
	         console.log('右旋转 90度')  
	         canvas.width = height;    
	         canvas.height = width;    
	         ctx.rotate(degree);    
	         ctx.drawImage(img, 0, -height, width, height);    
	         break;    
	       case 2:    
	         //console.log('旋转 180度')  
	         canvas.width = width;    
	         canvas.height = height;    
	         ctx.rotate(degree);    
	         ctx.drawImage(img, -width, -height, width, height);    
	         break;    
	       case 3:    
	         console.log('左旋转 90度')  
	         canvas.width = height;    
	         canvas.height = width;    
	         ctx.rotate(degree);    
	         ctx.drawImage(img, -width, 0, width, height);  
	         break;    
	       default:  //不旋转  
	         canvas.width = width;  
	         canvas.height = height;  
	         ctx.drawImage(img, 0, 0, width, height);  
	         break;  
	     }  
	 
	     let baseStr = canvas.toDataURL("image/jpeg", 1);  
	     return baseStr;  
	 },
	 //-----------------------------------------------结束
	 uploadImg(tempFilePaths) {
			console.log(tempFilePaths,"触发上传接口")
			uni.uploadFile({
				url: '服务器地址',
				filePath: tempFilePaths,
				fileType:"image",
				header:{"Authorization":'Bearer ' + localStorage.getItem('token')},
				name: 'file',
				success: (res) => {
					uni.hideLoading()
					let resObj = JSON.parse(res.data)
					if (resObj.meta.code === 200) {
						let data = resObj.data.url;
						console.log(data)
					} 
				}
		}
	 
		好了,有什么问题欢迎大家一起讨论!
		最后非常感谢原文(https://ask.dcloud.net.cn/article/36521)提供的经验,谢谢谢谢
  • 4
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论
使用规范:  var file = $("#file_input")[0].files[0]; if(file.size / 1024 > 1024 * 5){ mui.toast('图片不能超过5M'); return; } //图片压缩 compress.rotatePhotoCompress(file,function(imageObj){ var formData = new FormData(); formData.append("uploadFile", imageObj, file.name); // 文件对象 //图片上传 uploadAdd(formData); }); /** * 图片上传 * @param formData */ function uploadAdd(formData){ var URL = apiUrl.addMultImageURL+"?plateTag=order&fileOwnerId=order&fileType=image&token;="+app.getToken(); $.ajax({ url: URL, //请求地址 type: "post", async: true, //默认为异步 data: formData, //参数 contentType: false, //数据请求格式 processData:false, xhr:function(){ myXhr = $.ajaxSettings.xhr(); if(myXhr.upload){ // check if upload property exists myXhr.upload.addEventListener('progress',function(e){ //显示进条 $("#progress1").show(); var loaded = e.loaded;//已经上传大小情况 var tot = e.total;//附件总大小 var per = Math.floor(100*loaded/tot); //已经上传的百分比 mui("#progress1").progressbar({progress:per}).show(); }, false); // for handling the progress of the upload } return myXhr; },// 成功 success: function (data) { //隐藏进条 $("#progress1").hide(); if (data.error == 0 && null != data.url) { mui.toast('上传图片成功'); $('.show_img').append("<div class='imgList'><span class='oClose'>X</span><img src="+app.fileUrl+data.url+"><input type='hidden' name='imgUrls["+count+"]' value="+data.url.replace(app.fileUrl,"")+"></div>"); count++; } else { mui.toast('上传图片失败'); $('#uploadPicButton').html('请你选择图片重新上传'); } }, error:function(rep) { $("#progress1").hide(); console.log(JSON.stringify(rep)); mui.toast('上传异常'); } }) }
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

咸鱼起码是条鱼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值