国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

JS移動端/H5同時選擇多張圖片上傳并使用canvas壓縮圖片

2019-11-19 16:17:53
字體:
來源:轉載
供稿:網友

最近在做一個H5的項目,里邊涉及到拍照上傳圖片的功能以及識別圖片的功能,這里對識別圖片的功能不做贅述,不屬本文范疇。我在做完并上線項目后,同事跟我提了一個要求是可不可以同時選擇多張圖片上傳,我做的時候的想法是如果給file表單加了 multiple 屬性就沒有辦法調用手機的攝像頭拍照了,如果不加,就無法同時選擇多張圖片,于是我就照實跟同事說了這個情況。但回頭一想,單張圖片可以上傳,那多張圖片呢?于是就有了本文的內容。

HTML5定義了 FileReader 作為文件 API 的重要成員用于讀取文件,根據 W3C 的定義,FileReader接口提供了讀取文件的方法和包含讀取結果的事件模型。

FileReader的實例擁有 4 個方法,其中 3 個用以讀取文件,另一個用來中斷讀取。下面的表格列出了這些方法以及他們的參數和功能,需要注意的是 ,無論讀取成功或失敗,方法并不會返回讀取結果,這一結果存儲在 result 屬性中。

方法名 參數 描述
abort none 中斷讀取
readAsBinaryString file 將文件讀取為二進制碼
readAsDataURL file 將文件讀取為 DataURL
readAsText file, [encoding] 將文件讀取為文本

readAsText:該方法有兩個參數,其中第二個參數是文本的編碼方式,默認值為 UTF-8。這個方法非常容易理解,將文件以文本方式讀取,讀取的結果即是這個文本文件中的內容。

readAsBinaryString:該方法將文件讀取為二進制字符串,通常我們將它傳送到后端,后端可以通過這段字符串存儲文件。

readAsDataURL:這是例子程序中用到的方法,該方法將文件讀取為一段以 data: 開頭的字符串,這段字符串的實質就是 Data URL,Data URL是一種將小文件直接嵌入文檔的方案。這里的小文件通常是指圖像與 html 等格式的文件。

FileReader還包含了一套完整的事件模型,用于捕獲讀取文件時的狀態,下面這個表格歸納了這些事件。

事件 描述
onabort 中斷時觸發
onerror 出錯時觸發
onload 文件讀取成功完成時觸發
onloadend 讀取完成觸發,無論成功或失敗
onloadstart 讀取開始時觸發
onprogress 讀取中

文件一旦開始讀取,無論成功或失敗,實例的 result 屬性都會被填充。如果讀取失敗,則 result 的值為 null ,否則即是讀取的結果,絕大多數的程序都會在成功讀取文件的時候,抓取這個值。

了解了H5提供的 FileReader 后,我們就使用 FileReader 來實現同事選擇多張圖片并上傳。

首先,在 HTML 加入一個file表單,并設置其為 multiple(瀏覽器在對multiple、disabled、checked、selected等這類屬性進行解析時,只要這些屬性存在,默認的就會被解析成true,甭管你設置的是disabled=true或者disabled=false亦或是disabled="",如果不想這些屬性起作用,唯有用js來remove掉這些屬性,除非你不設置這些屬性。),并設置accept="image/*"用以只能選擇圖片類型的文件,代碼如下:

<input type="file" accept="image/*" name="upload" id="upload" multiple><input type="hidden" id="hiddenImgUrl" />  <!--設置這個隱藏域是為了便于存放上傳至服務器后返回的圖片地址-->

接下來就到了js上場了:

//圖片上傳var file = {  upload: function (e) {    var self = this;    var files = e.target.files;    var type = files[0].type.split('/')[0];    if (type != 'image') {      alertMsg('請上傳圖片');      return;    }    //var size = Math.floor(file.size / 1024 / 1024);    //if (size > 3) {    //  alert('圖片大小不得超過3M');    //  return;    //};    for (var i = 0; i < files.length; i++) {      var reader = new FileReader();      reader.readAsDataURL(files[i]);      reader.onloadstart = function () {        //用以在上傳前加入一些事件或效果,如載入中...的動畫效果      };      reader.onloadend = function (e) {        var dataURL = this.result;        var imaged = new Image();        imaged.src = dataURL;        imaged.onload = function () {  //利用canvas對圖片進行壓縮          var canvas = document.createElement('canvas');          var ctx = canvas.getContext('2d');          var w = 0;          var h = 0;          if (this.width > this.height) {            h = 1000;            var scale = this.width / this.height;            h = h > this.height ? this.height : h;            w = h * scale;          }          else {            w = 1000;            var scale = this.width / this.height;            w = w > this.width ? this.width : w            h = w / scale;          }          var anw = document.createAttribute("width");          var anh = document.createAttribute("height");          if (this.width > this.height) {            anw.value = h;            anh.value = w;          }          else {            anw.value = w;            anh.value = h;          }          canvas.setAttributeNode(anw);          canvas.setAttributeNode(anh);          if (this.width > this.height) {            ctx.translate(h, 0);            ctx.rotate(90 * Math.PI / 180)            ctx.drawImage(this, 0, 0, w, h);            ctx.restore();          }          else {            ctx.drawImage(this, 0, 0, w, h);          }          dataURL = canvas.toDataURL('image/jpeg');          //回調函數用以向數據庫提交數據          self.callback(dataURL);        };      };    }  },  event: function () {    $("#upload").change(function (e) {            file.upload(e);    });  },  callback: function (dataURL) {    $.ajaxSettings.async = false;  //這里必須將ajax的異步改為同步才可以把返回并保存在隱藏域中的圖片地址取出同時加在地址欄中作為參數一并傳入下一個頁面,這樣做的目的是因為返回的圖片地址不是一個json數組,而是單個的json字符串,所以只能將返回的圖片地址json字符串拼接在一起作為參數傳到下一個頁面    $.post(url, dataURL, function (res) {  //將base64圖片流的圖片通過后臺轉換成普通的圖片路徑并上傳至服務器      var imgUrl = $("#hiddenImgUrl").val();      if (res.success) {        $(".loading").hide();        if (imgUrl != "") {          $("#hiddenImgUrl").val(imgUrl + "|" + res.imgUrl);  //中間加一個 | 是為了到下一個頁面便于將傳過去的圖片地址參數轉換為數組        } else {          $("#hiddenImgUrl").val(res.imgUrl);        }        var imgUrl = $("#hiddenImgUrl").val();        window.location.href = "apply.html?imgUrl=" + imgUrl;      } else {        alert(res.message);      }    }, "json");  },  init: function () {    this.event();  }}file.init();

由于在通過post向服務器上傳時采用了同步的方式,所以我在寫項目的過程中,老是無法實現加載中的動畫效果,并且把加載中的動畫效果放在 reader.onloadstart方法中依舊不起作用,最后只能放在了$("#upload").change(function (e) {})方法中,代碼如下:

event: function () {    $("#upload").change(function (e) {      $(".loading").show();           file.upload(e);    });  }

以上是同時上傳多張圖片并將圖片傳入下一個頁面繼續進行后續操作,那么如何在同時上傳完多張圖片后在本頁再預覽這些圖片呢?其實方法也是很簡單的,上邊callback函數里邊的$.post的返回值里就包含了上傳至服務器后的圖片路徑,將這些路徑賦給img標簽的src,然后再插入到頁面中就OK了,代碼如下:

callback: function (dataURL) {        $.post(url, dataURL, function (res) {  //將base64圖片流的圖片通過后臺轉換成普通的圖片路徑并上傳至服務器      if (res.success) {        $(".loading").hide();        var result = '<div class="result"><img src="'+res.imgUrl+'" alt=""/></div>';        var div = document.createElement('div');        div.innerHTML = result;        document.body.appendChild(div);              } else {        alert(res.message);      }    }, "json");  }

以上在預覽圖片時由于不需要跳轉,不需要傳入返回的所有圖片的路徑作為參數,所以也就不需要將ajax的異步設置為同步了。

以上所述是小編給大家介紹的JS移動端/H5同時選擇多張圖片上傳并使用canvas壓縮圖片,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對武林網網站的支持!

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 广西| 濮阳县| 阿城市| 昌邑市| 青浦区| 广德县| 余江县| 安仁县| 越西县| 郯城县| 石渠县| 门源| 开鲁县| 长海县| 望江县| 洱源县| 石狮市| 休宁县| 峨山| 弥勒县| 蚌埠市| 称多县| 上蔡县| 新安县| 和政县| 铜陵市| 正阳县| 神农架林区| 郎溪县| 泰宁县| 高邮市| 东阳市| 安达市| 临沭县| 金门县| 文山县| 资兴市| 浦北县| 搜索| 永吉县| 获嘉县|