在开始之前需要了解为什么在浏览器中图片会自动旋转,在一些相机设备中因手持方向的原因导致图片会有一个旋转角度,在浏览器中旋转角度被忽略了,导致图片看过去是旋转的
图片旋转如下
如图
1 正常
6 旋转90°
8 旋转-90°
3 旋转180°
既然知道了图片需要旋转的角度,那么只需要通过canvas旋转并绘制图片,然后将图片输出就行,这里需要借助exif-js获取图片的源信息,只需要判断 Orientation 然后旋转对应的角度,废话不多说上代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
body{
padding-left: 300px;
}
.preivew {
width: 300px;
}
.preivew2 {
width: 300px;
}
</style>
<!-- 这里采用cdn形式引入exif -->
<script src="https://cdn.jsdelivr.net/npm/exif-js"></script>
</head>
<body>
<input type="file" accept="image/*" />
<p>转换前</p>
<img class="preivew" />
<p>转换后</p>
<img class="preivew2" />
</body>
</html>
<script>
// 添加input事件监听
document.querySelector('input').addEventListener('change', onFileChange)
function onFileChange(event) {
let file = event.target.files[0] // 得到file对象
document.querySelector('.preivew').src = URL.createObjectURL(file) // 转换前的img
rotateImg(file).then(blob => {
document.querySelector('.preivew2').src = URL.createObjectURL(blob) // 转换后的img
// 上传获取到的blob对象
// let fromData = new fromData()
// fromData.appendChild('file',blob)
// $.ajax({
// type: "method",
// url: "url",
// data: "data",
// dataType: "dataType",
// success: function (response) {
// }
// });
/*
*这里把转换后的blob对象下载在电脑上查看,实际开发中忽略
*/
const url = window.URL.createObjectURL(blob)
const link = document.createElement('a')
link.href = url
link.setAttribute('download', 'AAAAAA')
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
window.URL.revokeObjectURL(url)
})
}
function rotateImg(file) {
return new Promise((resolve, reject) => {
let img = new Image();
img.src = window.URL.createObjectURL(file);
img.onload = () => {
// 获取图片源数据 上面已经引入EXIF全局变量
EXIF.getData(img, function () {
// 获取图片orientation值
console.log(EXIF.getAllTags(this))
let orientation = EXIF.getTag(this, "Orientation");
let canvas = document.createElement("canvas");
let ctx = canvas.getContext("2d");
switch (orientation) {
case 3: // 旋转180°
canvas.width = img.width;
canvas.height = img.height;
ctx.rotate((180 * Math.PI) / 180);
ctx.drawImage(img, -img.width, -img.height, img.width, img.height);
break;
case 6: // 旋转90°
canvas.width = img.height;
canvas.height = img.width;
ctx.rotate((90 * Math.PI) / 180);
ctx.drawImage(img, 0, -img.height, img.width, img.height);
break;
case 8: // 旋转-90°
canvas.width = img.height;
canvas.height = img.width;
ctx.rotate((-90 * Math.PI) / 180);
ctx.drawImage(img, -img.width, 0, img.width, img.height);
break;
default: // 没有源信息的图片和正常的图片是不需要旋转的
canvas.width = img.width;
canvas.height = img.height;
ctx.drawImage(img, 0, 0, img.width, img.height);
break;
}
// 处理完返回 (这里返回都是被压缩的,根据实际情况更改正常的图片处理方式)
canvas.toBlob(file => resolve(file), 'image/jpeg', 0.92)
})
}
})
}
</script>
看看效果