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>