本文实例为大家分享了js移动端拍摄图片旋转的具体代码,供大家参考,具体内容如下
第一步:引入exif-js
<script src="https://cdn.jsdelivr.net/npm/exif-js@2.3.0/exif.min.js"></script>
第二步:
/**
* 处理图片文件(处理移动端拍摄图片旋转问题)
* fileObj.file 图片文件独享
* fileObj.resolution 在指定图片格式为 image/jpeg 或 image/webp的情况下,可以从 0 到 1 的区间内选择图片的质量。
* fileObj.fileType 输入的文件类型,1 file对象,2 blob对象,3 base64字符串
* fileObj.fileName 输出的文件名称,默认为picture.jpeg
* fileObj.callback 回调函数
*/
function handleImageFile(fileObj) {
// 给参数附初始值
fileObj.fileName = fileObj.hasOwnProperty("fileName") ? "images/" + fileObj.fileName : "images/picture.jpeg";
// 获取文件类型
var fType = fileObj.file.type;
if (fType.indexOf("image") === -1) return fileObj.callback({
status: 500,
message: "文件类型不正确",
data: null
});
if (!EXIF) return fileObj.callback({
status: 500,
message: "EXIF 不存在",
data: null
});
if (fileObj.file) {
// 获取照片方向角属性,用户旋转控制
EXIF.getData(fileObj.file, function () {
var 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 canvas = document.createElement("canvas");
var ctx = canvas.getContext("2d");
var resultFile = null;
var ua = navigator.userAgent;
canvas.width = this.naturalWidth;
canvas.height = this.naturalHeight;
ctx.drawImage(this, 0, 0, this.naturalWidth, this.naturalHeight);
// android终端
var isAdr = ua.indexOf("Android") > -1 || ua.indexOf("Adr") > -1;
// ios终端
var isIOS = ua.indexOf("iPhone") > -1 || ua.indexOf("iOS") > -1;
// 修复ios 或 Android
if (isIOS || isAdr) {
// 如果方向角不为1,都需要进行旋转
if (orientation && orientation !== "" && orientation !== 1) {
switch (orientation) {
case 6: // 需要顺时针(向左)90度旋转
rotateImg(this, "left", canvas);
break;
case 8: // 需要逆时针(向右)90度旋转
rotateImg(this, "right90", canvas);
break;
case 3: // 需要180度旋转,转两次
rotateImg(this, "right180", canvas);
break;
}
}
resultFile = canvas.toDataURL("image/jpeg", fileObj.resolution);
} else {
resultFile = canvas.toDataURL("image/jpeg", fileObj.resolution);
}
switch (fileObj.fileType) {
case 1:
case 2:
fileObj.callback({
status: 200,
message: "success",
data: dataURLtoFile(resultFile, fileObj.fileType, fileObj.fileName)
});
break;
case 3:
fileObj.callback({
status: 200,
message: "success",
data: resultFile
});
break;
default:
break;
}
};
};
oReader.readAsDataURL(fileObj.file);
});
} else {
return fileObj.callback({
status: 500,
message: "文件不存在",
data: null
});
}
/**
* 旋转图片
*/
function rotateImg(img, direction, canvas) {
if (img === null) return;
// 最小与最大旋转方向,图片旋转4次后回到原方向
var minStep = 0;
var maxStep = 3;
// img的高度和宽度不能在img元素隐藏后获取,否则会出错
var width = img.width;
var height = img.height;
var step = 2;
if (step === null) step = minStep;
if (direction === "right90") {
step++;
step > maxStep && (step = minStep);
} else if(direction === "right180") {
step = 2;
} else {
step--;
step < minStep && (step = maxStep);
}
// 旋转角度以弧度值为参数
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, width, height);
break;
case 1:
canvas.width = height;
canvas.height = width;
ctx.rotate(degree);
ctx.drawImage(img, 0, -height, width, height);
break;
case 2:
canvas.width = width;
canvas.height = height;
ctx.rotate(degree);
ctx.drawImage(img, -width, -height, width, height);
break;
case 3:
canvas.width = height;
canvas.height = width;
ctx.rotate(degree);
ctx.drawImage(img, -width, 0, width, height);
break;
}
}
/**
* type:1 file对象,2 blob对象
*/
function dataURLtoFile(dataurl, type, filename) {
var arr = dataurl.split(',');
var mime = arr[0].match(/:(.*?);/)[1];
var bstr = atob(arr[1]);
var n = bstr.length;
var u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
if (type === 1) { // 转换成file对象
return new File([u8arr], filename, {
type: mime
});
} else { // 转换成成blob对象
return new Blob([u8arr], {
type: mime
});
}
}
}