【uniapp】解决H5上传照片部分机型 照片角度自动旋转

下载依赖  cnpm install exif --save
页面引用

import EXIF from "exif-js"

首先获取 file对象 
uni.chooseImage({
		count: 1,
		sizeType: ['compressed'],
		sourceType: ['album'], //这要注意,camera掉拍照,album是打开手机相册
		success: (res) => {
				console.log(res);
				this.imgUrl = res.tempFilePaths[0]
				this.files = []
				let a = res.tempFiles[0]
				this.detail(this.imgUrl, a.name) //调用方法 
				let url = window.webkitURL.createObjectURL(a);
				}
		});

上面所调用的方法
//url 就是上面获取到的blod
			async detail(url, imgName) {
				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;
				})
				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")
				let file = this.base64ToFile(
					baseStr,
					imgName
				);
				this.aFile = file
			},

			//-------------------------------直接粘贴的三个方法 上面调用的
			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;
							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
					uni.getImageInfo({
						src: file,
						success(res) {
							console.log(imgObj)
							
							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);
				this.baseStr = baseStr
				return baseStr;
			},

这个方法实验后只在安卓上生效了 ios 直接使用的input file方式上传
然后lrz方法压缩 之后进行上传

//判断机型
var u = navigator.userAgent;
			var isAndroid = u.indexOf('Android') > -1 || u.indexOf('Linux') > -1; //android终端或者uc浏览器
			var isiOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); //ios终端
			if (isiOS) {
				
				this.tipFlag = 'ios'
			}
			if (isAndroid) {
				
				this.tipFlag = 'Android'
			}
 //template中’
<view class="text_right " ref="input1"  v-if="tipFlag == 'ios'"> 
//script中
mounted() {
			// 创建附件上传
			if(this.tipFlag == 'ios'){
				var input1 = document.createElement('input');//创建元素
				input1.type = 'file'//添加file类型
				input1.onchange = (event) => {
					this.upFile(input1, event)
				}
				this.$refs.input1.$el.appendChild(input1)
			}
			
			// this.galleryImg()
		},
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值