您好,登錄后才能下訂單哦!
小編給大家分享一下使用H5做出上傳圖片功能的方法,希望大家閱讀完這篇文章后大所收獲,下面讓我們一起去探討吧!
知識點:input file、base64、FileReader、canvas壓縮、blob、btoa編碼和atob解碼、FormData。
html dom節點:
<input type="file">
默認可以選擇一個文件。需要上傳多張。可以增加multiple="true" 屬性。一般使用opacity:0;將默認樣式隱藏,然后再重新寫其樣式。
1、創建對象
var fileReader = new FileReader();
2、判斷瀏覽器是否兼容----ie8下不支持
if( window.FileReader )
3、狀態常量
常量名 | 值 | 描述 |
EMPTY | 0 | 為開始讀取文件 |
LOADING | 1 | 文件讀取中 |
DONE | 2 | 文件讀取完成 |
在下面例子中,可以分別讀取當前狀態。
4、屬性
屬性名 | 描述 |
error | 讀取文件時發生錯誤 |
readyState | 當前fileReader對象的狀態,為上述狀態常量的一個 |
result | 讀取到的內容 |
5、方法
方法名 | 參數 | 描述 |
abort | 無 | 中止讀取,在非LOADING狀態時調用會拋出異常 |
readAsArrayBuffer | blob/file | 讀取為數組,在result中有一個ArrayBuffer對象為讀取的內容 |
readAsBinaryString | blob/file | 讀取為二進制,在result中有讀取文件的原始二進制 |
readAsDataUrl | blob/file | 讀取為dataUrl,在result中有data:url格式的字符串表示讀取的內容 |
readAsTexx | blob/file , [encoding] | 讀取為文本,在result中字符串表示讀取的內容 |
6、事件處理
事件 | 描述 |
onabort | 中斷時觸發 |
onerror | 出錯時觸發 |
onload | 讀取成功時觸發 |
onloadend | 讀取完成時觸發(不論成功是否) |
onloadstart | 讀取開始時觸發 |
onprocess | 讀取中觸發 |
BASE64:
我們用chrome打開一張圖片,在resources里面顯示的就是圖片的base編碼(實際上base編碼比原圖片稍大)
圖片的base64編碼也就是將一張圖片編碼成一個字符串,我們可以用這個字符串給img標簽的src賦值,這樣我們就可以看到這張圖片。
如何編寫:
在html中:
<img src="data:image/gif;base64,R0lGODlhAwADAIABAL6+vv///yH5BAEAAAEALAAAAAADAAMAAAIDjA9WADs=">
在css中:
background-image:url(data:image/gif;base64,R0lGODlhBAABAIABAMLBwfLx8SH5BAEAAAEALAAAAAAEAAEAAAICRF4AOw==);
優缺點:
優點:1、減少了http請求;2、可以被gzip;3、沒有跨域問題;4、無需考慮在更新圖片時緩存問題。
缺點:1、ie8以下不支持;2、不論是寫在css文件還是html文件中,增加了文件的大小;3、圖片大了之后,程序員編碼相當困難;
應用:
根據實際需求來選擇base64顯示圖片,或者選擇css sprite,或者直接使用png等
一般使用場景:很少被更新,實際尺寸很小,在系統中大量使用。
canvas壓縮:
在移動應用場景中,用戶上傳的圖片一般很大,會導致上傳時間過長而失敗,既浪費時間也浪費流量,更影響用戶體驗。我們可以使用canvas的drawImage方法的圖形裁剪功能。
1、新建image對象,給其src復制base64值,在其監聽onload事件;
2、在onload事件方法中新建canvas對象,獲取上下文context;
3、設置裁剪比例,調用drawImage方法填充圖片。
4、通過toDataUrl方法獲取裁剪之后的base64值。
詳細見下例。
Blob
在傳輸一些比較大的圖片的base64是容易出現轉發錯誤,這里我們可以將base64轉換成blob字段寫到form表單中提交到后臺。一般blob和base64之間的相互轉換通過fileReader 的readAsDataUrl和ArrayBuffer的charCodeAt方法。下面列舉幾個相互轉換的方法。來自(http://jsperf.com/blob-base64-conversion)
var blobToBase64 = function(blob, cb) {
var reader = new FileReader();
reader.onload = function() {
var dataUrl = reader.result;
var base64 = dataUrl.split(',')[1];
cb(base64);
};
reader.readAsDataURL(blob);
};
var base64ToBlob = function(base64, cb) {
var binary = atob(base64);
var len = binary.length;
var buffer = new ArrayBuffer(len);
var view = new Uint8Array(buffer);
for (var i = 0; i < len; i++) {
view[i] = binary.charCodeAt(i);
}
cb(new Blob([view]));
};
var base64ToBlobSync = function(base64) {
var binary = atob(base64);
var len = binary.length;
var buffer = new ArrayBuffer(len);
var view = new Uint8Array(buffer);
for (var i = 0; i < len; i++) {
view[i] = binary.charCodeAt(i);
}
var blob = new Blob([view]);
return blob;
};
var blobToBase64_2 = function(blob, cb) {
var reader = new FileReader();
reader.onload = function() {
var buffer = reader.result;
var view = new Uint8Array(buffer);
var binary = String.fromCharCode.apply(window, view);
var base64 = btoa(binary);
cb(base64);
};
reader.readAsArrayBuffer(blob);
};
btoa 與 atob: ---在對base64轉blob時就需要用atob對base64進行解碼
btoa("javascript"); //"amF2YXNjcmlwdA==" atob("amF2YXNjcmlwdA==") ; //"javascript"
注意:在需要轉碼中文時,需要用encodeURIComponent方法對中文處理,解碼時用decodeURIComponent
btoa(encodeURIComponent("我喜歡 javascript")); //"JUU2JTg4JTkxJUU1JTk2JTlDJUU2JUFDJUEyJTIwamF2YXNjcmlwdA==" decodeURIComponent(atob("JUU2JTg4JTkxJUU1JTk2JTlDJUU2JUFDJUEyJTIwamF2YXNjcmlwdA==")); //"我喜歡 javascript" FormData:
我們只需要使用new FormData()創建對象,然后append鍵值對,后用ajax向后臺發生即可。
這里是往FormData對象添加blob字段。
注:使用Ajax將這個FormData
對象提交到服務器上時,所發送的HTTP請求頭中代表那個Blob
對象所包含文件的文件名稱的"Content-Disposition"請求頭的值會是一個空字符串,這會引發某些服務器程序上的錯誤.從Gecko
7.0開始,這種情況下發送的文件名稱改為"blob"這個字符串.
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=0"> <title>Document</title> <script src="http://apps.bdimg.com/libs/zepto/1.1.4/zepto.min.js"></script> <!--引用baidu--> </head> <style> .uploadPic{ width: 92%; position: relative; margin: 0 auto; height: 2.8rem; line-height: 2.8rem; font-size: 1.3rem; border-radius: 4px; color: #fff; text-align: center; background-color: #72bcc5; } .uploadPic>input{ position: absolute; display: block; width: 100%; height: 100%; right: 0; top: 0; opacity: 0; } .uploadPic>img{ border:none; } </style> <body> <p id="uploadPic" class="uploadPic"> <span>拍攝</span> <input type="file" > <!--這里可以添加multiple="true"屬性,用來添加多張圖片,然后對this.file[]數組操作--> <p style="line-height: 1rem;margin: 0.5rem 0;"><progress id="progress" value="0" max="100" style="width: 100%;"></progress></p> <img src="" width="100%" style="height: 21rem;"> </p> </body> <script> function upload(file, callBack) { var loading=0; var total=file.size; if(window.FileReader){ $("#progress")[0].value=0; var fileReader = new FileReader(); fileReader.onload = function() { console.log(fileReader.readyState); //讀取完成 compressPic(this.result,callBack) }; fileReader.onerror = function() { console.log(fileReader.error); }; fileReader.onprogress = function (e){ console.log(fileReader.readyState); //讀取中 loading += e.loaded; $("#progress")[0].value=(loading / total) * 100; } console.log(fileReader.readyState); //未讀取 fileReader.readAsDataURL(file) }else{ alert("您的瀏覽器不支持FileReader"); } } function base64ConvertToBlob(picData, type, size) { type = type || ""; size = size || 512; var decodeFileData = atob(picData); //此處用atob解碼,轉碼函數btoa。在使用方法時注意操作中文時,需對中文decodeURIComponent轉換 var dataArray = []; var len = decodeFileData.length; for (var i = 0; i < len; i += size) { var pieceData = decodeFileData.slice(i, i + size); //這里做了一個512的分組 var arr = new Array(pieceData.length); for (var j = 0; j < pieceData.length; j++) { arr[j] = pieceData.charCodeAt(j) } var u8a = new Uint8Array(arr); dataArray.push(u8a) } return new Blob(dataArray, {type: type}) } function compressPic(picData,callBack) { var img=new Image(); img.onload = function(){ var width = img.width; var height = img.height; var standard=800; //以800為基準壓縮 if (width > standard || height > standard) { var rate = Math.max(width / standard, height / standard); width /= rate; height /= rate } var canvas = document.createElement("canvas"); canvas.width = width; canvas.height = height; var context = canvas.getContext("2d"); context.fillRect(0, 0, canvas.width, canvas.height); context.drawImage(img, 0, 0, width, height); var data = canvas.toDataURL("image/jpeg", 1); //var blobData=base64ConvertToBlob(data.replace(/^.*?,/, ""), "image/jpeg") //-----需要去掉符號,不然使用atob方法報錯 //doAjax(new FormData().append('image',data)); //后續可以這樣做,轉換成Blob字段,組裝FormData,發送至后臺 console.log("the after canvas compress size : " + data.length); callBack(data) }; img.src=picData; console.log("the before canvas conpress size : "+picData.length); } $("#uploadPic input").change(function() { var file=this.files[0]; upload(file, function(picData){ $("#uploadPic img")[0].src = picData; //預覽 } ); }); </script> </html>
看完了這篇文章,相信你對使用H5做出上傳圖片功能的方法有了一定的了解,想了解更多相關知識,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。