上篇博文【 Js利用Canvas實現圖片壓縮 】中做了圖片壓縮上傳,但是在IOS真機測試的時候,發現圖片預覽的時候自動逆時針旋轉了90度。對於這個bug,我完全不知道問題出在哪里,接下來就是面向百度編程了。通過度娘找到了相關資料,解決方法記錄在此。這個問題的具體因素其實我還是不清楚是為何導致的,只有IOS和部分三星手機會出現此bug。 絕大部分的安卓機並無此問題。
解決此問題需要引入一個第三方 JS 庫: exif.js 下載地址:https://github.com/exif-js/exif-js 通過exif.js 我們可以獲取到圖片的元信息,這其中就包括照片的拍照方向。而 exif.js 給出的照片方向屬性如下圖:
IOS中通過 exif.js ,獲取拍照的圖片的方向,返回的值為 6, 也就是上圖最左邊的 F 的情況。 這也正是我們的bug所在。 因此我們通過判斷方向的值來做相應的處理,如果值為 6 ,則我們對圖片進行旋轉矯正。具體代碼如下:
// 調整圖片方向 function adjustImgOrientation (ctx, img, orientation, width, height) { switch (orientation) { case 3: ctx.rotate(180 * Math.PI / 180); ctx.drawImage(img, -width, -height, width, height); break; case 6: ctx.rotate(90 * Math.PI / 180); ctx.drawImage(img, 0, -width, height, width); break; case 8: ctx.rotate(270 * Math.PI / 180); ctx.drawImage(img, -height, 0, height, width); break; case 2: ctx.translate(width, 0); ctx.scale(-1, 1); ctx.drawImage(img, 0, 0, width, height); break; case 4: ctx.translate(width, 0); ctx.scale(-1, 1); ctx.rotate(180 * Math.PI / 180); ctx.drawImage(img, -width, -height, width, height); break; case 5: ctx.translate(width, 0); ctx.scale(-1, 1); ctx.rotate(90 * Math.PI / 180); ctx.drawImage(img, 0, -width, height, width); break; case 7: ctx.translate(width, 0); ctx.scale(-1, 1); ctx.rotate(270 * Math.PI / 180); ctx.drawImage(img, -height, 0, height, width); break; default: ctx.drawImage(img, 0, 0, width, height); } }
// 添加圖片 $('#choose_img').on('change', function (e) { let file = e.target.files[0]; // 讀取圖片元數據:方向 let orient; EXIF.getData(file, function () { EXIF.getAllTags(this); orient = EXIF.getTag(this, 'Orientation'); let base64 = ''; let reader = new FileReader(); reader.onload = function () { let image = new Image(); image.src = this.result; image.onload = function() { let canvas = document.createElement("canvas"); let ctx = canvas.getContext("2d"); canvas.width = 150; canvas.height = 150; // 解決png黑色背景 ctx.fillStyle = "#fff"; ctx.fillRect(0, 0, 150, 150); // 調整圖片方向問題 adjustImgOrientation(ctx, this, orient, 150, 150); base64 = canvas.toDataURL("image/jpeg", 0.8); console.log('base64', base64); model.user_image = base64; $('#preview-img').attr('src', base64).show(); } }; reader.readAsDataURL(e.target.files[0]); });
OK, 問題解決!參考資料:http://blog.csdn.net/hsany330/article/details/52471522