/** * 將base64轉換爲文件對象 * (即用文件上傳輸入框上傳文件獲得的對象) * @param {String} base64 base64字符串 */ function convertBase64UrlToBlob(base64){ var base64Arr = base64.split(','); if(base64Arr.length > 1){ //若是是圖片base64,去掉頭信息 base64 = base64Arr[1]; } // 將base64解碼 var bytes = atob(base64); var bytesCode = new ArrayBuffer(bytes.length); // 將base64轉換爲ascii碼 for (var i = 0; i < bytes.length; i++) { bytesCode[i] = bytes.charCodeAt(i); } // 轉換爲類型化數組 var byteArray = new Uint8Array(bytesCode); // 生成Blob對象(文件對象) return new Blob( [byteArray] , {type : 'image/png'}); }
/** * 壓縮圖片 * (壓縮後返回的是base64,能夠參照本目錄下的convertBase64ToBlob.js,將base64還原爲file input讀取獲得的文件對象) * @param {Dom Object} $fileInput 文件上傳輸入框 * @param {Function} callback 壓縮完成後的回調函數 * @return {Object} options 指定壓縮到指定體積如下或按比率壓縮,不指定不會壓縮 */ function compressImg($fileInput, callback, options) { options = options || {}; // 綁定change事件 $fileInput.onchange = function ($event) { var $target = $event.target; if ($target.files && $target.files[0]) { // 用FileReader讀取文件 var reader = new FileReader(); // 將圖片讀取爲base64 reader.readAsDataURL($fileInput.files[0]); reader.onload = function(evt){ var base64 = evt.target.result; // 建立圖片對象 var img = new Image(); // 用圖片對象加載讀入的base64 img.src = base64; img.onload = function () { var that = this, canvas = document.createElement('canvas'), ctx = canvas.getContext('2d'); canvas.setAttribute('width', that.width); canvas.setAttribute('height', that.height); // 將圖片畫入canvas ctx.drawImage(that, 0, 0, that.width, that.height); // 壓縮到指定體積如下(M) if(options.size){ var scale = 0.9; while (base64.length / 1024 / 1024 > options.size) { // 用canvas的toDataURL方法實現壓縮 base64 = canvas.toDataURL('image/jpeg', scale); // 下降壓縮比率,直到壓縮結果小於指定大小 scale = scale - 0.1; } } else if(options.scale){ // 按比率壓縮 base64 = canvas.toDataURL('image/jpeg', options.scale); } callback(base64); } } } } }
/** * 上傳以前預覽圖片 * @param {Dom Object} $fileInput 文件上傳輸入框 * @param {Dom Object} $previewImg 預覽圖片的image元素 */ function previewImg($fileInput, $previewImg) { $fileInput.onchange = function ($event) { var $target = $event.target; if ($target.files && $target.files[0]) { var reader = new FileReader(); reader.readAsDataURL($target.files[0]); reader.onload = function(evt){ var base64 = evt.target.result; $previewImg.setAttribute('src', base64); } } } }
/** * 將圖片旋轉到正確的角度 * (解決移動端上傳的圖片角度不正確的問題) * (旋轉後返回的是base64,能夠參照本目錄下的convertBase64ToBlob.js,將base64還原爲file input讀取獲得的文件對象) * @param {Dom Object} $fileInput 文件上傳輸入框 * @param {Function} callback 旋轉完成後的回調函數 */ function resetImgOrientation($fileInput, callback) { // 綁定change事件 $fileInput.onchange = function ($event) { var $target = $event.target; if ($target.files && $target.files[0]) { // 獲取圖片旋轉角度 getOrientation($target.files[0], function (orientation) { var reader = new FileReader(); reader.readAsDataURL($target.files[0]); reader.onload = function(evt){ var base64 = evt.target.result; // 將圖片旋轉到正確的角度 resetOrientation(base64, orientation, function (resultBase64) { callback(resultBase64); }); } }); } } } // 獲取圖片旋轉的角度 function getOrientation(file, callback) { var reader = new FileReader(); reader.readAsArrayBuffer(file); reader.onload = function(e) { var view = new DataView(e.target.result); if (view.getUint16(0, false) != 0xFFD8) return callback(-2); var length = view.byteLength, offset = 2; while (offset < length) { var marker = view.getUint16(offset, false); offset += 2; if (marker == 0xFFE1) { if (view.getUint32(offset += 2, false) != 0x45786966) return callback(-1); var little = view.getUint16(offset += 6, false) == 0x4949; offset += view.getUint32(offset + 4, little); var tags = view.getUint16(offset, little); offset += 2; for (var i = 0; i < tags; i++) if (view.getUint16(offset + (i * 12), little) == 0x0112) return callback(view.getUint16(offset + (i * 12) + 8, little)); } else if ((marker & 0xFF00) != 0xFF00) break; else offset += view.getUint16(offset, false); } return callback(-1); }; } // 將圖片旋轉到正確的角度 function resetOrientation(srcBase64, srcOrientation, callback) { var img = new Image(); img.onload = function() { var width = img.width, height = img.height, canvas = document.createElement('canvas'), ctx = canvas.getContext("2d"); // set proper canvas dimensions before transform & export if ([5,6,7,8].indexOf(srcOrientation) > -1) { canvas.width = height; canvas.height = width; } else { canvas.width = width; canvas.height = height; } // transform context before drawing image switch (srcOrientation) { case 2: ctx.transform(-1, 0, 0, 1, width, 0); break; case 3: ctx.transform(-1, 0, 0, -1, width, height ); break; case 4: ctx.transform(1, 0, 0, -1, 0, height ); break; case 5: ctx.transform(0, 1, 1, 0, 0, 0); break; case 6: ctx.transform(0, 1, -1, 0, height , 0); break; case 7: ctx.transform(0, -1, -1, 0, height , width); break; case 8: ctx.transform(0, -1, 1, 0, 0, width); break; default: ctx.transform(1, 0, 0, 1, 0, 0); } // draw image ctx.drawImage(img, 0, 0); // export base64 callback(canvas.toDataURL('image/jpeg')); }; img.src = srcBase64; };