2021-07-26

h5调用摄像头拍照部分手机旋转了90度解决方式

话不多说,整个代码整理头,过程有点复杂,需要静心看,使用exif-js与Canvas配合旋转回来,一环套一环,差点绕晕了,期间再百度上借鉴了其他人的解决方案,我都没走通,最后一个总算是走通了,也是看了好久,调整了好久才出来的结果,本代码是使用uniapp唤起拍照功能上传图片的完全体方法,部分未完善,请各位多多指出问题

<template>
	<view class="content">
		<image :src="src" style="width: 500upx 400upx;" id="img1"  mode="widthFix"  lazy-load></image>  
		<view class="text-area">
			<text class="title">{{title}}</text>
			<button type="default" @click="paizhao">拍照</button>
		</view>
	</view>
</template>

<script>
	import EXIF from 'exif-js'
	export default {
		data() {
			return {
				title: 'Hello',
				src:""
			}
		},
		onLoad() {

		},
		methods: {
            paizhao(){
				uni.chooseImage({
				    count: 1, //默认9
				    sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
				    sourceType: ['camera '], //从相册选择
				    success:(res)=>{
						let imgArr = res.tempFilePaths; // 所选择图片的临时路径数组
						//BlobUrl转blob数据
						
						// uni.showToast({
						// 	icon: "none",
						// 	title: "图片处理中..."
						// })
						//blob数据转file
											this.objectURLToBlob(imgArr[0], (blob)=>{
												console.log(blob)
							// 					console.log(blob)
												let files = new window.File([blob], 'heard', { type: blob.type });
												console.log('获取图片文件', files);
												EXIF.getData(files, async()=>{
													let or = EXIF.getTag(files, 'Orientation'); //这个Orientation 就是我们判断需不需要旋转的值了,有1、3、6、8
													console.log(or);
													let Orientation = or;
													var img = null;
													var canvas = null;
													await this.comprossImage(imgArr[0], 600, function(e) {
														img = e.img;
														canvas = e.canvas;
													});
													let baseStr = '';
							// 						//如果方向角不为1,都需要进行旋转
													switch (Orientation) {
														case 6: //需要顺时针(向右)90度旋转
															console.log('(向右)90度旋转');
															baseStr = this.rotateImg(img, 'right', canvas);
															break;
														case 8: //需要逆时针(向左)90度旋转
															console.log('向左)90度旋转');
															baseStr = this.rotateImg(img, 'left', canvas);
															break;
						 
														case 3: //需要180度旋转 转两次
															console.log('需要180度旋转');
															baseStr = this.rotateImg(img, 'right', canvas, 2);
															break;
														default:
															baseStr = this.rotateImg(img, '', canvas);
															break;
													}
												});
											});
										}
								
				    
				});
			},
			objectURLToBlob(url, callback) {
						var http = new XMLHttpRequest();
						http.open('GET', url, true);
						http.responseType = 'blob';
						http.onload = function(e) {
							console.log(e)
							if (e.currentTarget.status == 200 || e.currentTarget.status === 0) {
								callback(e.currentTarget.response);
							}
						};
						http.send();
					},
			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));
						}
					});
				});
			},
					
					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 = 600;
								let canvasWidth = width; //图片原始长宽
								let canvasHeight = height;
								let base = canvasWidth / canvasHeight;
								console.log(base);
								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:
										//不旋转
										console.log('不旋转');
										canvas.width = width;
										canvas.height = height;
										ctx.drawImage(img, 0, 0, width, height);
										break;
								}
					 
								let baseStr = canvas.toDataURL('image/jpeg', 1);
								// console.log(baseStr)
								// return baseStr;
								// replace("data:image/jpeg;base64,", "")
					            // 将base64转化为blob文件进行图片上传,(考虑到转化后再上传耗费时间暂时没有使用,如果需要base64ToPath 方法可百度或者私信我)
								// base64ToPath(baseStr).then(tempPath => {
								// 	this.uploadBgImg(tempPath)
								// });
					            // 自定义上传请求
								// this.uploadBaseImg(baseStr);
								this.src = baseStr
								console.log(baseStr)
							},
		}
	}
</script>

<style>
	.content {
		display: flex;
		flex-direction: column;
		align-items: center;
		justify-content: center;
	}

	.logo {
		height: 200rpx;
		width: 200rpx;
		margin-top: 200rpx;
		margin-left: auto;
		margin-right: auto;
		margin-bottom: 50rpx;
	}

	.text-area {
		display: flex;
		justify-content: center;
	}

	.title {
		font-size: 36rpx;
		color: #8f8f94;
	}
</style>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值