Js(基於jQuey)網頁端壓縮圖片後上傳伺服器
問題前述:為了保證邏輯更清晰,文章採用不少的文字解析,如果你比較緊急,可以不用看文字直接瀏覽程式碼呈現部分。
問題背景:最近有做到一個需求,使用者實名認證上傳身份證,一般情況下直接通過手機拍照上傳這樣的圖片很大(大約2-4M),一方面浪費伺服器頻寬,另外一方面上傳的速度很慢,體驗效果也不是很好。
解決方案:前端進行圖片預處理,先縮放一下圖片之後再上傳到後端處理。
思考過程:
(1)目前瀏覽器上傳圖片到伺服器的過程有兩種,一種是通過普通檔案上傳,即<form enctype="multipart/form-data">這種模式 ,另一種是方式就是通過檔案的base64位編碼,然後上傳這段code後端解析這段code,這樣便可以脫離檔案本身。
(2)通常上傳圖片的時候是通過<input type="file" />表單控制元件來上傳,可不可以通過獲取圖片連結壓縮這個圖片後來上傳呢,這樣是不行的,首先目前很多瀏覽器從隱私的角度上看,是不允許獲取到完成的圖片路徑的,其次要是我們真的壓縮了檔案,那不是改變了原始檔,也道理上也是不允許的,瀏覽器只能引用這個圖片。
(3)綜合上述兩點,通過獲取檔案的base64位編碼來上傳圖片是比較合理的,就需要通過瀏覽器壓縮原有的圖片得到壓縮圖片的base64點陣圖片的code上傳。
技術分析:需要瀏覽器支援h5,然後使用h5內建的canvas技術來壓縮圖片,目前主流的瀏覽器都已經支援h5,尤其是在wap端,可以放心使用,不過在pc上,一些低版本的瀏覽器可能不支援,需要適當做好相容性。具體情況可以參考這篇文章,https://www.zhihu.com/question/19613759。
程式碼呈現:這裡通過一段完整的ajax方式來展示圖片的壓縮過程(基於jQuery環境,請在頭部新增)。
//核心程式碼 壓縮圖片並返回base64code ratio表示圖片質量0-1之間 function resizeImage(img,width,height,ratio){ var canvas, ctx, baseCode64; canvas = document.createElement('canvas'); canvas.width = width; canvas.height = height; ctx = canvas.getContext("2d"); ctx.drawImage(img, 0, 0, width, height); baseCode64 = canvas.toDataURL("image/jpeg", ratio); return baseCode64; } /* *在你的網頁裡面應該有一個元素 *<input type="file" accept="image/gif, image/jpeg" onchange="startUpload(this)" data-remote="上傳圖片的url"> */ function startUpload(obj){ var input=obj; if(input.files){ var imageName=obj.files[0];//獲取file檔名 //讀取圖片資料 var f = input.files[0]; /***************************核心程式碼 reader方法讀取圖片 start************************/ var reader = new FileReader(); reader.onload = function (e) { var data = e.target.result; //載入圖片獲取圖片真實寬度和高度 var image = new Image(); image.onload=function(){ var width = image.width; var height = image.height; //圖片預判斷,獲取上傳圖片的的大小 if(width<640){ alert("圖片的長不能小於640畫素!"); }else if(height<480){ alert("圖片的寬不能小於480畫素!"); } //圖片上傳 else{ var base64=resizeImage(image,width,height,1); //$('body').html('<img src="'+base64+'">');return;除錯圖片的壓縮結果 var url=$(obj).data('remote'); //發起非同步傳輸請求,將壓縮後圖片的base64編碼傳送到伺服器供解析 $.ajax({ type:'post', url: url, //用於檔案上傳的伺服器端請求地址 data:{ image:base64, image_name:imageName }, dataType: 'json', //返回值型別 一般設定為json success: function (rs) //伺服器成功響應處理函式 { //伺服器響應成功處理函式,您可以在裡面進行資料處理 }, error: function (data, status, e)//伺服器響應失敗處理函式 { alert(e); } }); } }; image.src= data; }; reader.readAsDataURL(f); /**核心程式碼 reader方法讀取圖片 end****/ }else{ alert("未檢測到圖片!"); } }
技術點總結:
(1)Js壓縮前端圖片
(2)base64點陣圖片編碼
(3)獲取file控制元件的檔名
(4)Js獲取圖片檔案的長度和寬度