本文实例为大家分享了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,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,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,width,height); break; case 1: canvas.width = height; canvas.height = width; ctx.rotate(degree); ctx.drawImage(img,-height,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,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 }); } } }