1. 程式人生 > >Js(基於jQuey)網頁端壓縮圖片後上傳伺服器

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獲取圖片檔案的長度和寬度