溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

使用H5做出上傳圖片功能的方法

發(fā)布時(shí)間:2020-09-28 15:50:19 來源:億速云 閱讀:195 作者:小新 欄目:web開發(fā)

小編給大家分享一下使用H5做出上傳圖片功能的方法,希望大家閱讀完這篇文章后大所收獲,下面讓我們一起去探討吧!

知識(shí)點(diǎn):input file、base64、FileReader、canvas壓縮、blob、btoa編碼和atob解碼、FormData。

html dom節(jié)點(diǎn):

<input type="file">

默認(rèn)可以選擇一個(gè)文件。需要上傳多張??梢栽黾觤ultiple="true" 屬性。一般使用opacity:0;將默認(rèn)樣式隱藏,然后再重新寫其樣式。

1、創(chuàng)建對(duì)象

var fileReader = new FileReader();

2、判斷瀏覽器是否兼容----ie8下不支持

if( window.FileReader )

3、狀態(tài)常量

常量名描述
EMPTY0為開始讀取文件
LOADING1文件讀取中
DONE2文件讀取完成

在下面例子中,可以分別讀取當(dāng)前狀態(tài)。

4、屬性

屬性名描述
error讀取文件時(shí)發(fā)生錯(cuò)誤
readyState當(dāng)前fileReader對(duì)象的狀態(tài),為上述狀態(tài)常量的一個(gè)
result讀取到的內(nèi)容

5、方法

方法名參數(shù)描述
abort中止讀取,在非LOADING狀態(tài)時(shí)調(diào)用會(huì)拋出異常
readAsArrayBufferblob/file讀取為數(shù)組,在result中有一個(gè)ArrayBuffer對(duì)象為讀取的內(nèi)容
readAsBinaryStringblob/file讀取為二進(jìn)制,在result中有讀取文件的原始二進(jìn)制
readAsDataUrlblob/file讀取為dataUrl,在result中有data:url格式的字符串表示讀取的內(nèi)容
readAsTexxblob/file , [encoding]讀取為文本,在result中字符串表示讀取的內(nèi)容

6、事件處理

事件描述
onabort中斷時(shí)觸發(fā)
onerror出錯(cuò)時(shí)觸發(fā)
onload讀取成功時(shí)觸發(fā)
onloadend讀取完成時(shí)觸發(fā)(不論成功是否)
onloadstart讀取開始時(shí)觸發(fā)
onprocess讀取中觸發(fā)

BASE64:

我們用chrome打開一張圖片,在resources里面顯示的就是圖片的base編碼(實(shí)際上base編碼比原圖片稍大)

圖片的base64編碼也就是將一張圖片編碼成一個(gè)字符串,我們可以用這個(gè)字符串給img標(biāo)簽的src賦值,這樣我們就可以看到這張圖片。

如何編寫:

在html中:

<img src="data:image/gif;base64,R0lGODlhAwADAIABAL6+vv///yH5BAEAAAEALAAAAAADAAMAAAIDjA9WADs=">

在css中:

background-image:url(data:image/gif;base64,R0lGODlhBAABAIABAMLBwfLx8SH5BAEAAAEALAAAAAAEAAEAAAICRF4AOw==);

優(yōu)缺點(diǎn):

優(yōu)點(diǎn):1、減少了http請(qǐng)求;2、可以被gzip;3、沒有跨域問題;4、無需考慮在更新圖片時(shí)緩存問題。

缺點(diǎn):1、ie8以下不支持;2、不論是寫在css文件還是html文件中,增加了文件的大小;3、圖片大了之后,程序員編碼相當(dāng)困難;

應(yīng)用:

根據(jù)實(shí)際需求來選擇base64顯示圖片,或者選擇css sprite,或者直接使用png等

一般使用場(chǎng)景:很少被更新,實(shí)際尺寸很小,在系統(tǒng)中大量使用。

canvas壓縮:

在移動(dòng)應(yīng)用場(chǎng)景中,用戶上傳的圖片一般很大,會(huì)導(dǎo)致上傳時(shí)間過長而失敗,既浪費(fèi)時(shí)間也浪費(fèi)流量,更影響用戶體驗(yàn)。我們可以使用canvas的drawImage方法的圖形裁剪功能。

1、新建image對(duì)象,給其src復(fù)制base64值,在其監(jiān)聽onload事件;

2、在onload事件方法中新建canvas對(duì)象,獲取上下文context;

3、設(shè)置裁剪比例,調(diào)用drawImage方法填充圖片。

4、通過toDataUrl方法獲取裁剪之后的base64值。

詳細(xì)見下例。

Blob

在傳輸一些比較大的圖片的base64是容易出現(xiàn)轉(zhuǎn)發(fā)錯(cuò)誤,這里我們可以將base64轉(zhuǎn)換成blob字段寫到form表單中提交到后臺(tái)。一般blob和base64之間的相互轉(zhuǎn)換通過fileReader 的readAsDataUrl和ArrayBuffer的charCodeAt方法。下面列舉幾個(gè)相互轉(zhuǎn)換的方法。來自(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:      ---在對(duì)base64轉(zhuǎn)blob時(shí)就需要用atob對(duì)base64進(jìn)行解碼

btoa("javascript");     //"amF2YXNjcmlwdA=="
atob("amF2YXNjcmlwdA==") ;       //"javascript"

注意:在需要轉(zhuǎn)碼中文時(shí),需要用encodeURIComponent方法對(duì)中文處理,解碼時(shí)用decodeURIComponent

btoa(encodeURIComponent("我喜歡 javascript"));    //"JUU2JTg4JTkxJUU1JTk2JTlDJUU2JUFDJUEyJTIwamF2YXNjcmlwdA=="
decodeURIComponent(atob("JUU2JTg4JTkxJUU1JTk2JTlDJUU2JUFDJUEyJTIwamF2YXNjcmlwdA=="));   //"我喜歡 javascript"
FormData:

我們只需要使用new FormData()創(chuàng)建對(duì)象,然后append鍵值對(duì),后用ajax向后臺(tái)發(fā)生即可。

這里是往FormData對(duì)象添加blob字段。

注:使用Ajax將這個(gè)FormData對(duì)象提交到服務(wù)器上時(shí),所發(fā)送的HTTP請(qǐng)求頭中代表那個(gè)Blob對(duì)象所包含文件的文件名稱的"Content-Disposition"請(qǐng)求頭的值會(huì)是一個(gè)空字符串,這會(huì)引發(fā)某些服務(wù)器程序上的錯(cuò)誤.從Gecko 7.0開始,這種情況下發(fā)送的文件名稱改為"blob"這個(gè)字符串.

使用H5做出上傳圖片功能的方法

<!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"屬性,用來添加多張圖片,然后對(duì)this.file[]數(shù)組操作-->
 <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解碼,轉(zhuǎn)碼函數(shù)btoa。在使用方法時(shí)注意操作中文時(shí),需對(duì)中文decodeURIComponent轉(zhuǎn)換
            var dataArray = [];
            var len = decodeFileData.length;
            for (var i = 0; i < len; i += size) {
                var pieceData = decodeFileData.slice(i, i + size);   //這里做了一個(gè)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為基準(zhǔn)壓縮
         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")  //-----需要去掉符號(hào),不然使用atob方法報(bào)錯(cuò)
         //doAjax(new FormData().append('image',data));   //后續(xù)可以這樣做,轉(zhuǎn)換成Blob字段,組裝FormData,發(fā)送至后臺(tái)
         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;    //預(yù)覽
            }
        );
    });
</script>
</html>

看完了這篇文章,相信你對(duì)使用H5做出上傳圖片功能的方法有了一定的了解,想了解更多相關(guān)知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道,感謝各位的閱讀!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI