項目回顧1-圖片上傳-form表單仍是base64-前端圖片壓縮

第一個項目終於上線了,是一個叫親青籌的公益衆籌平臺,微信端,電腦端還有後臺界面大部分都是我完成的,幾個月過來,感受收穫了不少,以爲要總結一下。css

首先想到的是圖片上傳的問題。在一般表單數據都是ajax上傳的狀況下,爲了上傳圖片而去使用form表單感受很蠢。而後那時候也沒有想到用jquery form插件。html

後臺的同事給的方案是用iframe裏寫一個form表單,而後上傳圖片以後自動提交表單,他將圖片在服務器上的地址以跳轉頁url的一部分,我再來截取的方式。前端

方案一:iframe+form表單html5

    <form action="/user/uploadIdCard.do" class="fileForm picUpload" enctype="multipart/form-data" method="post">
        <input type="file" id="uploadPic" name="file">
        <label for="uploadPic" id="fileBtn">
            +
            <img src="" />
        </label>
        <input type="text" name="turnUrl" class="turnUrl">
    </form>

 

    $(".turnUrl").val(window.location.pathname);
    $("#uploadPic").on('change', function(event) {
        event.preventDefault();
        $("form").submit();
    });

在須要上傳圖片的界面引入iframe,在調用公用庫裏的iframe方法,得到圖片的url而且把圖片顯示在iframe中jquery

// 提取iframe裏的路徑
function iframe(el) {
    var baseurl = "";
    var code, filePath;
    var place = $(el)[0].contentWindow.location.search;
    console.log(place);
    if (place) {
        code = place.match(/code=\d+/)[0].substr(5);
        if (place.match(/filepath=\S+/)) {
            filePath = place.match(/filepath=\S+/)[0].substr(9);
        }
        $(el).contents().find(".tip").css('color', '#d0021b');
        console.log(filePath);
        switch (code) {
            case "200":
                $(el).contents().find(".tip").text('上傳成功');
                $(el).contents().find(".tip").css('color', '#55a012');
                $(el).contents().find("#fileBtn>img").show().attr("src", baseurl + "/" + filePath);
                return "/" + filePath;
            case "206":
                $(el).contents().find(".tip").text('文件過大');
                break;
            case "207":
                $(el).contents().find(".tip").text('文件類型錯誤');
                break;
            case "208":
                $(el).contents().find(".tip").text('系統錯誤');
        }
    }
}

方案二:後來發現這樣的作法有兩個問題,一個是用戶發的圖片太大,後臺沒有作壓縮(後臺的同事太忙了,爲了遷就他們,就咱們前端作壓縮了)。第二個是,上傳圖片成功以後,圖片顯示在iframe上,這樣須要必定的反應時間,使用者有時候會反映圖片傳不上去,其實只是後臺尚未返回……web

因而決定用base64上傳到後臺的方式ajax

    <input type="file" id="uploadPic" name="file">
    <label for="uploadPic" id="fileBtn">
        +
        <img class="showPic" src="" />
    </label>
    <span class="tip">請上傳圖片,大小在2M之內<br/>(圖片類型可爲jpg,jepg,png,gif,bmp)<br/>推薦圖片比例爲640*400</span>
    <input type="text" name="turnUrl" class="turnUrl">
    <canvas id="uploadImg" style="display:none"></canvas>

結構和原來差很少,只是多了一個canvascanvas

    $("#uploadPic").on('change', function(event) {
        event.preventDefault();
        console.log($(this)[0].files);
        var file = $(this)[0].files[0];
        if(file.size>2097152){
            alert("上傳圖片請小於2M");
            return false;
        }        if (!/image\/\w+/.test(file.type)) {
            alert("文件必須爲圖片!");
            return false;
        }
        var reader = new FileReader();
        reader.readAsDataURL(file);
        reader.onload = function(e) {
                createCanvas(this.result);
            }
    });

    function createCanvas(src) {
        var canvas = document.getElementById("uploadImg");
        var cxt = canvas.getContext('2d');
        canvas.width = 640;
        canvas.height = 400;
        var img = new Image();
        img.src = src;
        img.onload = function() {
            // var w=img.width;
            // var h=img.height;
            // canvas.width= w;
            // canvas.height=h;
            cxt.drawImage(img, 0, 0,640,400);
            //cxt.drawImage(img, 0, 0);
            $(".showPic").show().attr('src', canvas.toDataURL("image/jpeg", 0.9));
            $.ajax({
                url: "/front/uploadByBase64.do",
                type: "POST",
                data: {
                    "imgStr": canvas.toDataURL("image/jpeg", 0.9).split(',')[1]
                },
                success: function(data) {
                    console.log(data);
                    $(".showPic").show().attr('data-url',"/"+ data.url);
                }
            });
        }
    }

1.首先是用的input的file文件的信息,判斷文件大小file.size,以及文件是否爲圖片file.type服務器

2.再經過html5的FileReader接口來得到這個圖片的base64數據微信

3.將這個base64傳入canvas中,做爲一張圖的src,這時候能夠設置圖片的分辨率大小,保證上傳的圖都是統一的分辨率。固然也能夠按照圖片原來的大小。

4.在ajax以前,把處理後的base64直接顯示出來(這樣用戶就能夠馬上看到本身上傳的圖片),再將 canvas.toDataURL("image/jpeg", 0.9).split(',')[1] (類型爲image/jpeg,就能夠用第二個參數來設置畫質了)傳到後臺對應的接口

5.再將後臺返回的url 綁在圖片的data-url屬性上,在ajax上交整個表單時獲取這個data-url就行了,這樣用戶能夠最快時間看到,而url其實還在ajax到後臺的過程當中

後記:這兩個方案都有一個問題,會給後臺上傳不少冗餘圖片。不事後臺的同事貌似沒什麼意見,囧。

實際效果是這樣的 http://www.qqchou.org/qqcweb/pages/photoIframe.html 

相關文章
相關標籤/搜索