移动端h5页面,input上传图片,有时候,在pc端查看时翻转90度。
解决方案1:待验证
1、使用exif.js获取图片信息 再用canvas旋转后 转base64 再转
<script src="js/exif.js"></script>
var file = document.querySelector('input[type=file]').files[0];//IE10以下不支持
EXIF.getData(file, function() {
var Orientation = EXIF.getTag(this, 'Orientation');
if(Orientation && Orientation != 1){//图片角度不正确
fileFun(Orientation,file);
}else{
//不需处理直接上传
}
});
//base64格式图片 转为Blob
function dataURLtoBlob(dataurl) {
var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1],
bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
while(n--){
u8arr[n] = bstr.charCodeAt(n);
}
return new Blob([u8arr], {type:mime});
}
//图片处理函数
function fileFun(Orientation,file){
var reader = new FileReader();
var image = new Image();
reader.readAsDataURL(file);
reader.onload = function (ev) {
image.src = ev.target.result;
image.onload = function () {
var imgWidth = this.width,
imgHeight = this.height; //获取图片宽高
var canvas=document.getElementById("myCanvas");
var ctx = canvas.getContext('2d');
canvas.width = imgWidth;
canvas.height = imgHeight;
if(Orientation && Orientation != 1){
switch(Orientation){
case 6: // 旋转90度
canvas.width = imgHeight;
canvas.height = imgWidth;
ctx.rotate(Math.PI / 2);
ctx.drawImage(this, 0, -imgHeight, imgWidth, imgHeight);
break;
case 3:// 旋转180度
ctx.rotate(Math.PI);
ctx.drawImage(this, -imgWidth, -imgHeight, imgWidth, imgHeight);
break;
case 8: // 旋转-90度
canvas.width = imgHeight;
canvas.height = imgWidth;
ctx.rotate(3 * Math.PI / 2);
ctx.drawImage(this, -imgWidth, 0, imgWidth, imgHeight);
break;
}
}else{
ctx.drawImage(this, 0, 0, imgWidth, imgHeight);
}
var dataurl=canvas.toDataURL("image/jpeg", 0.8);//canvase 转为base64
var blob = dataURLtoBlob(dataurl);//base64转为blog
}
}
}
针对iphone手机进行方向判断,可行。
//上传文件
const uploadFile = function(file, success, failed, maxSize) {
console.log("newFile.name", file.name)
console.log("file.size", file.size / 1024 + "KB")
fixImageOrientation(file, (newFile) => {
console.log("newFile.size", newFile.size / 1024 + "KB")
let serveToken = getLocalStorage("serveToken")
let param = new FormData(); //创建form对象
param.append('file', newFile); //通过append向form对象添加数据
param.append('fileName', file.name); //通过append向form对象添加数据
let config = {
headers: {
'Content-Type': 'multipart/form-data',
'serveToken': serveToken,
},
//withCredentials: true,
}; //添加请求头
//axios.post(HOST + FILE_UPLOAD + "?access_token=undefined", param, config)
//axios.post(BASE_URL + API.file_upload_compress, param, config)
axios.post(BASE_URL + API.file_upload, param, config)
.then(response => {
console.log("上传结果", response.data);
if (response && response.data.resultCode == '0000') {
if (success && typeof success == "function") {
success(response.data.data)
// if (response.data.data && response.data.data.fileId) {
// request(API.file_bind, {
// fileId: response.data.data.fileId
// });
// }
}
} else {
if (failed && typeof failed == "function") {
failed()
}
}
}).catch(function(error) {
console.error("上传异常", error)
if (failed && typeof failed == "function") {
failed(error)
}
});
}, maxSize)
}
//获取照片方向角属性,用户旋转控制
function fixImageOrientation(file, callback, maxSize) {
EXIF.getData(file, function() {
EXIF.getAllTags(this);
console.log("Orientation", EXIF.getTag(this, 'Orientation'));
Orientation = EXIF.getTag(this, 'Orientation');
var oReader = new FileReader();
oReader.onload = function(e) {
var image = new Image();
image.src = e.target.result;
image.onload = function() {
var expectWidth = this.naturalWidth;
var expectHeight = this.naturalHeight;
var canvas = document.createElement("canvas");
var ctx = canvas.getContext("2d");
canvas.width = expectWidth;
canvas.height = expectHeight;
ctx.drawImage(this, 0, 0, expectWidth, expectHeight);
if (navigator.userAgent.match(/iphone/i)) {
console.log('iphone');
if (Orientation != "" && Orientation != 1) {
switch (Orientation) {
case 6: //需要顺时针(向左)90度旋转
console.log('需要顺时针(向左)90度旋转');
rotateImg(this, 'left', canvas);
break;
case 8: //需要逆时针(向右)90度旋转
console.log('需要顺时针(向右)90度旋转');
rotateImg(this, 'right', canvas);
break;
case 3: //需要180度旋转
console.log('需要180度旋转');
rotateImg(this, 'right', canvas); //转两次
rotateImg(this, 'right', canvas);
break;
}
}
}
let dUrl = canvas.toDataURL("image/jpeg", 0.8);
let newFile = convertBase64UrlToBlob(dUrl)
//let newFile = dataURLtoFile(dUrl, file.name)
if (callback && typeof callback == "function") {
quality = 1
compress(newFile, (result) => {
callback(result)
}, maxSize)
}
};
};
oReader.readAsDataURL(file);
});
}
//对图片旋转处理 added by lzk
function rotateImg(img, direction, canvas) {
//alert(img);
//最小与最大旋转方向,图片旋转4次后回到原方向
var min_step = 0;
var max_step = 3;
//var img = document.getElementById(pid);
if (img == null) return;
//img的高度和宽度不能在img元素隐藏后获取,否则会出错
var height = img.height;
var width = img.width;
//var step = img.getAttribute('step');
var step = 2;
if (step == null) {
step = min_step;
}
if (direction == 'right') {
step++;
//旋转到原位置,即超过最大值
step > max_step && (step = min_step);
} else {
step--;
step < min_step && (step = max_step);
}
var degree = step * 90 * Math.PI / 180;
var ctx = canvas.getContext('2d');
switch (step) {
case 0:
canvas.width = width;
canvas.height = height;
ctx.drawImage(img, 0, 0);
break;
case 1:
canvas.width = height;
canvas.height = width;
ctx.rotate(degree);
ctx.drawImage(img, 0, -height);
break;
case 2:
canvas.width = width;
canvas.height = height;
ctx.rotate(degree);
ctx.drawImage(img, -width, -height);
break;
case 3:
canvas.width = height;
canvas.height = width;
ctx.rotate(degree);
ctx.drawImage(img, -width, 0);
break;
}
}
function convertBase64UrlToBlob(urlData) {
var bytes = window.atob(urlData.split(',')[1]); //去掉url的头,并转换为byte
//处理异常,将ascii码小于0的转换为大于0
var ab = new ArrayBuffer(bytes.length);
var ia = new Uint8Array(ab);
for (var i = 0; i < bytes.length; i++) {
ia[i] = bytes.charCodeAt(i);
}
let blob = new Blob([ab], {
type: 'image/jpeg',
});
return blob
}
function compress(file, callBack, maxSize) {
let size = file.size;
console.log("file.size:", size / 1024 + "KB")
if (size > maxSize && quality != 0) {
quality -= 0.1
console.log("quality:", quality)
new Compressor(file, {
quality: quality,
maxWidth: 1080,
maxHeight: 1280,
success(result) {
if (result.size > maxSize) {
compress(result, callBack, maxSize)
} else {
callBack(result)
}
},
error(e) {
console.log("压缩错误:", e)
}
})
} else {
callBack(file)
}
}