移動應用中用戶往往需要上傳照片,但是用戶上傳的照片尺寸通常很大,而手機的流量卻很有限,所以在上傳前對圖像進行壓縮是很有必要的。
原生應用可以直接對文件進行處理,網頁應用就沒有這個優勢了。不過 canvas 的出現給出一條新的思路,將圖像按照比例繪制到畫布上,最后將繪制完成的畫布以 base64 編碼方式發送到服務端,再由服務端進行解析還原成圖片。
由於進行處理的過程較為復雜,於是 localResizeIMG 就孕育而生了,它簡化了前端壓縮圖片的步驟,減輕了前端工程師的工作負擔。Github:https://github.com/think2011/localResizeIMG
localResizeIMG 插件的優勢:
- 經過大量測試,特別適合在移動設備上使用
- 會根據對應設備自動載入JS文件,節省寬帶
- 基於原生 JavaScript 編寫,支持 AMD 規范
localResizeIMG 的獲取方式:
- GitHub:https://github.com/think2011/localResizeIMG
- NPM命令:npm install lrz
- BOWER:bower install lrz
======================前端代碼=========================
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>localResizeIMG</title> <!--引入JQuery 用於異步上傳圖片--> <script type="text/javascript" src="dist/jquery-3.1.1.min.js"></script> <!--引入 lrz 插件 用於壓縮圖片--> <script type="text/javascript" src="dist/lrz.bundle.js"></script> </head> <body> <input type="file" accept="image/jpeg" capture="camera"> </body> <script> $("input[type=file]").change(function () { /* 壓縮圖片 */ lrz(this.files[0], { width: 300 //設置壓縮參數 }).then(function (rst) { /* 處理成功后執行 */ rst.formData.append('base64img', rst.base64); // 添加額外參數 $.ajax({ url: "upload.php", type: "POST", data: rst.formData, processData: false, contentType: false, success: function (data) { $("<img />").attr("src", data).appendTo("body"); } }); }).catch(function (err) { /* 處理失敗后執行 */ }).always(function () { /* 必然執行 */ }) }) </script> </html>
引入插件:<script type="text/javascript" src="dist/lrz.bundle.js"></script>
綁定事件:$("input[type=file]").change(function () {/* 壓縮上傳處理 */});
壓縮圖片:lrz(file, [options]);
file 通過 input:file 得到的文件,或者直接傳入圖片路徑
[options] 這個參數允許忽略
width {Number} 圖片最大不超過的寬度,默認為原圖寬度,高度不設定時會適應寬度
height {Number} 圖片的最大高度,默認為原圖高度
quality {Number} 圖片壓縮質量,取值 0 - 1,默認為 0.7
fieldName {String} 后端接收的字段名,默認:file
返回結果:promise 對象
then(rst) 處理成功后執行
rst.formData 后端可處理的數據
rst.file 壓縮后的file對象,如果壓縮率太低,將會是原始file對象
rst.fileLen 生成后的圖片的大小,后端可以通過此值來校驗是否傳輸完整
rst.base64 生成后的圖片base64,后端可以處理此字符串為圖片,也可以直接用於 img.src = base64
rst.base64Len 生成后的base64的大小,后端可以通過此值來校驗是否傳輸完整
rst.origin 也就是原始的file對象,里面存放了一些原始文件的信息,例如大小、日期等
異步上傳:processData 和 contentType 必須設為 false,否則服務端不會響應
======================后端代碼=========================
<?php $base64_image_content = $_POST['base64img']; $output_directory = './image'; //設置圖片存放路徑 /* 檢查並創建圖片存放目錄 */ if (!file_exists($output_directory)) { mkdir($output_directory, 0777); } /* 根據base64編碼獲取圖片類型 */ if (preg_match('/^(data:\s*image\/(\w+);base64,)/', $base64_image_content, $result)) { $image_type = $result[2]; //data:image/jpeg;base64, $output_file = $output_directory . '/' . md5(time()) . '.' . $image_type; } /* 將base64編碼轉換為圖片編碼寫入文件 */ $image_binary = base64_decode(str_replace($result[1], '', $base64_image_content)); if (file_put_contents($output_file, $image_binary)) { echo $output_file; //寫入成功輸出圖片路徑 }