前言:
- 目前测试图片旋转只会出现在ios H5版本上,咨询过同行和ios原生,图片旋转是会发生在canvas压缩或者裁剪上,原生暂未发现图片旋转。
解决思路:
- H5版本使用exif-js获取Orientation 获取图片旋转方向,使用canvans进行旋转。
代码
// #ifndef APP-PLUS
import Exif from "exif-js"
// #endif
//H5图片入口
const rotatePic = async function(file,name,success) {
if(!isPicture(name)) return null;
let Orientation = 1;
await getImageTag(file,(e)=>{
if(e != undefined) Orientation = e;
})
var img = null;
var canvas = null;
await comprossImage(file, function(e) {
img = e.img;
canvas = e.canvas;
})
let baseStr = '';
//如果方向角不为1,都需要进行旋转
switch(Orientation){
case 6://需要顺时针(向右)90度旋转
console.log('(向右)90度旋转');
baseStr = rotateImg(img,'right',canvas);
break;
case 8://需要逆时针(向左)90度旋转
console.log('向左)90度旋转');
baseStr = rotateImg(img,'left',canvas);
break;
case 3://需要180度旋转 转两次
console.log('需要180度旋转');
baseStr = rotateImg(img,'right',canvas, 2);
break;
default:
baseStr = rotateImg(img,'',canvas);
break;
}
return baseStr
}
/**
* @desc 获取图片信息,使用exif.js库,具体用法请在github中搜索
* home.php?mod=space&uid=275307 {Object} file 上传的图片文件
* home.php?mod=space&uid=161696 {Promise<Any>} 读取是个异步操作,返回指定的图片信息
*/
const getImageTag = function (file, 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)
let _this = this;
uni.hideLoading()
uni.getImageInfo({
src: file,
success(res) {
let obj = {
src:res.path
}
Exif.getData(obj, function () {
let or = Exif.getTag(this,'Orientation');//这个Orientation 就是我们判断需不需要旋转的值了,有1、3、6、8
resolve(suc(or))
});
}
})
});
}
//创建图片
const comprossImage = async (imgSrc, 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));
}
});
})
}
//网上提供的旋转function
const 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, 0, width, height);
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;
}
ios 系统版本13.4以上不需要进行图片旋转 ios 13.4以上竖拍 Orientation 依然会得到6 但是图片已经被系统调整到正常使用旋转后会导致图片被旋转2次
//ios 13.4以上不需要进行翻转
const getVersionRotate = () => {
var ua = navigator.userAgent.toLowerCase();
var ver= ua.match(/cpu iphone os (.*?) like mac os/);
let b = ver[1].replace(/_/g,".");
return toNum(b) >= toNum(13.4) ? false : true;
}
//计算版本号大小,转化大小
const toNum = (a) => {
var a=a.toString();
var c=a.split('.');
var num_place=["","0","00","000","0000"],r=num_place.reverse();
for (var i=0;i<c.length;i++){
var len=c[i].length;
c[i]=r[len]+c[i];
}
var res= c.join('');
return res;
}
// #ifndef APP-PLUS
//处理图片旋转 H5上传入口
if(getVersionRotate()) {
_file = await rotatePic (filePath, dir) || filePath;
}
// #endif
原生图片旋转解决思路
因为几个测试机未出现图片旋转问题,所以未进行旋转,解决思路为选择图片后 uni.getImageInfo(OBJECT) success中获取orientation 旋转参数,使用plus.zip.compressImage进行原生图片旋转