H5使用Base64和Canvas上傳圖片
阿新 • • 發佈:2019-02-03
最近在做一個班級通知的H5頁面,從拿到原型到開發出完整功能的過程中,解決了一些問題,現在記錄一下發布通知時遇到的難點和解決方法。
一、呼叫手機攝像頭和手機相簿選取照片
1、由於使用的是最接近原生Android的mui框架,所以最開始是準備用mui的plus來呼叫camera和gallery方法,但是後來發現一直出現plusReady未定義的錯誤,寫在plusReady中的程式碼沒有執行。 在DCloud中找到原因如下,普通瀏覽器裡沒有plus環境,只有HBuilder真機執行和打包後才能執行plus api,且個人嘗試在真機中也不能執行。公司使用mui在初始階段,本人更是小白,到了這裡最後還是決定使用JS來實現照片的選擇和上傳。2、使用input標籤可以設定 opacity:0 將已有的input格式隱藏,然後將文字資訊居中顯示。
<input style="opacity:0;width:1px" type="file" id="file_input" accept="image/*" multiple>選擇圖片</input>
二、Base64。
1、簡介。 Base64是一種用64個字元【A-Z a-z 0-9 + /】來表示任意二進位制資料的方法,常用於在URL、Cookie、數字證書籤名或網頁中傳輸少量二進位制資料。 將每3個位元組Byte即3*8=24bit,轉化為4組6個二進位制位,然後在6位的前面補兩個0,形成一個8位的位元組,若剩下的字元不足3個位元組,則用0填充,輸出字元使用'=',因此編碼後輸出的文字末尾可能會出現1或2個'='【解碼時會自動去掉2、為什麼使用Base64。① 減少HTTP請求數,提高頁面載入速度。對於只有幾個KB大小的圖片,進行HTTP請求附帶的額外資訊可能比圖片本身還大,當請求量大時,資料傳輸會變慢【以data:image/*;base64開頭】。② 將圖片使用Base64編碼後,可通過URL直接解碼檢視圖片,即內嵌到網頁中而不是去請求並載入進來。③ 可以防止因為一些相對路徑等問題導致的圖片404錯誤。3、Base64的缺點。① Base64是一種通過查表的編碼方法,不能用於加密,即使使用自定義的編碼表也不行。② 當需要傳輸的圖片在1M以上時【未確定臨界值】,在網頁中載入Base64會變得很慢,此時需對圖片進行壓縮處理。
三、使用Base64和Canvas儲存圖片的編碼。
1、使用FileReader將檔案轉化為Base64編碼。① 在H5中使用FileReader把檔案讀取到記憶體,並讀取檔案中的資料,以便對圖片進行預覽。② FileReader的readAsDataURL方法可以將讀取的檔案資料以DataURL的形式即Base64儲存,可在客戶端直接顯示。2、使用Canvas對圖片重新繪製並設定壓縮質量。① 將圖片轉化成Base64後,可以繪製到Canvas上並對圖片進行編輯操作。② 當編輯或壓縮完成後,可以使用Canvas的toDataURL方法輸出新圖片的Base64資料。HTML:<div class="row mui-input-row ">
<textarea id="container" name="txt" class="mui-input-clear question"
placeholder="請輸入正文(必填,最多輸入500個漢字)"></textarea>
<div class="add_picture_div">
<a href="#picture" class="add_picture"><img src="${base}/res/images/add.png"></a>
</div>
<div id="picture" class="mui-popover mui-popover-action mui-popover-bottom">
<ul class="mui-table-view">
<li class="mui-table-view-cell">
<input style="opacity:0;width:1px" type="file" id="file_input" accept="image/*" multiple>選擇圖片</input>
</li>
<li class="mui-table-view-cell"><a href="#"><b>取消</b></a></li>
</ul>
</div>
</div>
JavaScript:var myHtml="";
window.onload = function(){
var result,input = document.getElementById("file_input");
if(typeof FileReader==='undefined'){
result.innerHTML = "抱歉,你的瀏覽器不支援 FileReader";
input.setAttribute('disabled','disabled');
}else{
input.addEventListener('change',readFile,false);
}
function readFile(){
var iLen = this.files.length;
for(var i=0;i<iLen;i++){
if (!input['value'].match(/.jpg|.gif|.png|.bmp/i)){ //判斷上傳檔案格式
return alert("上傳的圖片格式不正確,請重新選擇");
}
var reader = new FileReader();
var fileName = this.files[i].name; // 獲取檔名
var fileType = this.files[i].type; // 檔案字尾
reader.readAsDataURL(this.files[i]); // 轉成base64,此方法執行完後,base64資料儲存在reader.result裡
reader.onload = function(e){
var image = new Image(); // 建立一個image物件,供canvas繪圖使用
image.src = this.result; // this.result即base64的資料
image.onload = function(){
var scale = 1;
var cvs = document.createElement('canvas');
if(this.width > 300 || this.height > 300){
if(this.width > this.height)
scale = 300 / this.width;
else scale = 300 / this.height;
}
cvs.width = scale * this.width; // 計算等比縮小後圖片寬
cvs.height = scale * this.height;
var ctx = cvs.getContext('2d'); // 返回一個用於在畫布上二維繪圖的環境
ctx.drawImage(this,0,0,cvs.width,cvs.height);
var newImage = cvs.toDataURL(fileType,0.7); // 重新生成圖片Base64,壓縮質量即壓縮率為0.7
myHtml += "<br><p style='text-align:center;'><img src='"+newImage+"'/></p>";
var aHtml = '<a href="#" class="add_picture"><img src="'+newImage+'"/></a>';
$(".add_picture_div").append(aHtml);
}
}
}
}
}
jQuery:$.ajax({
url:'${base}/classedit/notice/noticePublish',
type:"post",
data:{
ownerId:$("#clsId").val(), // 班級ID
listTitle:$("#title").val(),
txt:$("#container").val()+myHtml
},
success:function(result){
console.info(result);
if(result.status == true){
alert("釋出成功!");
window.location.href='toNoticeListPage?userId=${userId!'' }';
}else{
alert("釋出失敗!");
window.location.reload();
}
}
});
讓釋出的通知以原樣顯示到詳情頁中,可以使用<pre>標籤格式化 freemarker 取出的資料。pre 元素可定義預格式化的文字,被包圍在 pre 元素中的文字通常會保留空格和換行符,儲存到資料庫中的資料會以原格式顯示到頁面中。<div class="mui-media-body">
<h4>${cmsContentExt.title }</h4>
<h6 class="mt15">${cmsContentExt.author } ${cmsContentExt.releaseDate?string("yyyy-MM-dd HH:mm:ss") }</h6>
<h6 class="mui-ellipsis mt20 fong_gray">
<#if listCD ??>
<#list listCD as list>
${list.className }
</#list>
</#if>
</h6>
<span class="mt20 fong_gray"><pre>${cmsContentTxt.txt}</pre></span>
</div>
3、效果圖:① 釋出通知:
② 按Scale等比縮放圖片畫素:
③ 使用img{max-width:100%;} 設定,若圖片大於屏寬則100%顯示,圖片小於屏寬則顯示原圖。
至此,H5頁面釋出通知功能開發完成。