( ′◔ ‸◔`)現在的公司啊都流行混合開發,我們公司也不例外,非要把交互非常多的社區模塊用內嵌web頁展示,好吧好吧,畢竟有的應用也是這麼做的,那既然是社區就肯定少不了用戶上傳圖片的操作,在開發階段沒有發現任何問題,也是很奇怪,等到了測試階段,發現部分機型和IOS機型拍照之後,web頁獲取路徑之後 ...
( ′◔ ‸◔`)現在的公司啊都流行混合開發,我們公司也不例外,非要把交互非常多的社區模塊用內嵌web頁展示,好吧好吧,畢竟有的應用也是這麼做的,那既然是社區就肯定少不了用戶上傳圖片的操作,在開發階段沒有發現任何問題,也是很奇怪,等到了測試階段,發現部分機型和IOS機型拍照之後,web頁獲取路徑之後展示的圖片和圖片文件全不是正確的方向,旋轉了90°、180°的都有,於是去網上查找原因,結果就是……
大於2M的圖片!並且是豎拍的圖片!在生成照片的時候圖片的Orientation屬性會被重寫!!!!所以部分機型和IOS 都會出現旋轉的問題!
可惡!
當然方法也百度到了,只不過大部分都是只放了代碼,並沒有講解,其實理解了也非常簡單。
一、安裝插件 ︶︿︶
解決這個問題首先是要藉助插件的,因為我們前端旋轉了圖片只是在頁面上看上去旋轉了,並沒有解決根本問題,於是就要用到 exif.js這個工具。
https://www.npmjs.com/package/exif-js
一個強大的讀取圖片數據的工具,安裝也很簡單文檔里也有,就不多說了,因為我使用的是Vue,所以之間npm安裝後在需要使用的頁面引入:
import exif from "exif-js";
到這裡就算完成了插件的全部安裝;
二、開工!(^-^)V
首先在選擇框的change事件中我們直接調用exif的方法;
let Orientation = 0; exif.getData(e.target.files[0], function() { exif.getAllTags(this); Orientation = exif.getTag(this, 'Orientation'); }); //e.target.files[0]為獲取的第一個圖片文件,如果是多個圖片文件可進行遍歷
這時候我們就已經獲取到圖片的Orientation屬性了,這個屬性就是圖片的方向屬性,不同的值代表不同的方向:
圖片正常 | 1 |
圖片朝右 | 6 |
圖片朝左 | 8 |
圖片倒置 | 3 |
後來經過測試Orientation還會有一個值,就是0,當Orientation等於0的時候圖片是正常的,但0代表的意思,還沒有找到。
那麼現在就可以對圖片進行處理了let canvas = document.createElement("canvas");
let ctx = canvas.getContext("2d"); let width = img.width; let height = img.height; switch(orientation) { case 0: //不做任何處理直接畫圖 canvas.width = width; canvas.height = height; ctx.drawImage(img, 0, 0) break; case 1: //不做任何處理直接畫圖 canvas.width = width; canvas.height = height; ctx.drawImage(img, 0, 0) break; case 6: //圖片順時針旋轉90° canvas.height = width; canvas.width = height; ctx.rotate(Math.PI / 2); ctx.translate(0, -height); ctx.drawImage(img, 0, 0) break; case 3: //圖片旋轉180° canvas.height = height; canvas.width = width; ctx.rotate(Math.PI); ctx.translate(-width, -height); ctx.drawImage(img, 0, 0) break; case 8: //圖片逆時針旋轉90° canvas.height = width; canvas.width = height; ctx.rotate(-Math.PI / 2); ctx.translate(-height, 0); ctx.drawImage(img, 0, 0) break; case undefined: //不作任何處理直接畫圖 canvas.width = width; canvas.height = height; ctx.drawImage(img, 0, 0) break; }
let ndata=canvas.toDataURL("image/jpeg", 1);
這裡圖片的處理就是把圖片原原本本的在canvas上畫一遍,然後把它轉成正確的方向就可以了,那麼縮略圖就可以直接展示ndata就可以了。
但是這裡還只是一張圖片,我們不可能給後臺傳圖片base64碼過去,必須是圖片文件才可以,那麼這裡就要用到base64的轉碼。
首先是base64轉碼函數的封裝:
// base64轉成bolb對象 dataURItoBlob(base64Data) { let byteString; if(base64Data.split(",")[0].indexOf("base64") >= 0) byteString = atob(base64Data.split(",")[1]); else byteString = unescape(base64Data.split(",")[1]); let mimeString = base64Data .split(",")[0] .split(":")[1] .split(";")[0]; let ia = new Uint8Array(byteString.length); for(let i = 0; i < byteString.length; i++) { ia[i] = byteString.charCodeAt(i); } return new Blob([ia], { type: mimeString }); },
然後將上面我們轉換好的ndata通過base64轉換成圖片文件就可以了。
//調用轉換函數將base64碼轉換成圖片文件 let blob = this.dataURItoBlob(ndata); //將新文件名與原圖片文件保持一致 blob.name = e.target.files[0].name; //將新文件放到我們需要傳給後臺的文件數組裡 this.files.push(blob);
三、結束o(゚Д゚)っ
以上就是對圖片旋轉做的處理,很簡單,我們就可以理解為圖片的重繪。當然上面的方法只是單個圖片的轉換,如果用戶同時上傳了多個圖片,那麼就在對應的地方添加遍歷迴圈就可以了。
如果有不足的地方希望大家補充,有不對的地方也請大家批評指正。
如果還不太明白也可以通過我的聯繫方式進行討論。