我們上傳文件時(shí)可以直接使用<input type="file">
實(shí)現(xiàn)上傳功能,然而在實(shí)際項(xiàng)目開發(fā)中可能需要其他的上傳方式,比如先將圖片上傳到OSS中,然后獲取到圖片地址,最后再提交表單入庫
首先我們看FileReader()
這個(gè)方法
這個(gè)方法的描述:
FileReader 對象允許Web應(yīng)用程序異步讀取存儲(chǔ)在用戶計(jì)算機(jī)上的文件(或原始數(shù)據(jù)緩沖區(qū))的內(nèi)容
當(dāng)我們使用input獲取圖片后回顯,其中FileReader
對象中的方法readAsDataURL()
讀取指定的 Blob
或File
對象,讀取操作完成的時(shí)候,readyState
會(huì)變成已完成(DONE),并觸發(fā)loadend
事件
<form action="">
<input type="file" id="upBtn" name="">
<img src="" id="preview">
</form>
<script type="text/javascript">
$('#upBtn').on("change", function() {
if(this.files.length === 0) { return; }
var file = this.files[0];
//驗(yàn)證圖片文件
rFilter = /^(?:image\/bmp|image\/cis\-cod|image\/gif|image\/ief|image\/jpeg|image\/jpeg|image\/jpeg|image\/pipeg|image\/png|image\/svg\+xml|image\/tiff|image\/x\-cmu\-raster|image\/x\-cmx|image\/x\-icon|image\/x\-portable\-anymap|image\/x\-portable\-bitmap|image\/x\-portable\-graymap|image\/x\-portable\-pixmap|image\/x\-rgb|image\/x\-xbitmap|image\/x\-xpixmap|image\/x\-xwindowdump)$/i;
if (!rFilter.test(file.type)) { alert("You must select a valid image file!"); return; }
var reader = new FileReader();
reader.onload = function(event) {
var src = event.target.result;
$('#preview').attr("src", src);
}
if(this.files && this.files[0]) {
reader.readAsDataURL(file);
}
})
</script>
我們再看這三種方法toBlob()
, toDataURL()
, getImageData()
這三種方法需要使用canvas
,首先我們先建立一個(gè)canvas畫布
<canvas id="canvas" width="500" height="300" style="border:1px solid #d3d3d3;background:#ffffff;"></canvas>
<script type="text/javascript">
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var img = new Image();
img.src = "./images/head.png";
img.onload = function() {
ctx.drawImage(img, 0, 0);
}
</script>
我們在建立畫布的時(shí)候回遇到這樣幾個(gè)問題:
- 需要引用服務(wù)器中圖片
- 跨域問題
- onload問題
我們這里引用本地的絕對路徑時(shí)沒法顯示圖片,如果你的文件是file:///
開頭的也沒法引入圖片,因?yàn)槲沂褂玫氖莊is3,所以會(huì)自動(dòng)打開一個(gè)服務(wù)器
跨域問題沒找到解決的方法,貌似只靠前端是沒法解決的
先看看toBlob()
方法
這里的onload
事件內(nèi)部執(zhí)行canvas.toBlob()
方法時(shí)可以的所以我們img.onload
的代碼需要改成這樣
img.onload = function() {
ctx.drawImage(img, 0, 0);
//這段代碼放外面時(shí)圖片沒法加載
canvas.toBlob(function(blob) {
var newImg = document.createElement("img"),
url = URL.createObjectURL(blob);
newImg.onload = function() {
//釋放一個(gè)之前通過調(diào)用URL.createObjectURL()創(chuàng)建的已經(jīng)存在的 URL 對象。
URL.revokeObjectURL(url);
};
console.log(url); //blob:http://XXX/38a1135b-812e-4ab6-823c-cd0162662ff6
newImg.src = url;
document.body.appendChild(newImg);
})
}
toBlob()
默認(rèn)生成png
,如果需要生成jpeg
需要改變第二個(gè)參數(shù)
canvas.toBlob(function(blob){...}, "image/jpeg", 0.95); // JPEG 圖片質(zhì)量95%
這里生成的blob在前端做顯示圖片挺好用,但是往后臺(tái)傳輸圖片數(shù)據(jù)沒法傳遞,要靠base64傳遞
createObjectURL()
方法也可以顯示input type="file"
要上傳的圖片
<input type="file" id="file">
$('#file').on('change', function() {
var file = this.files[0];
var url = URL.createObjectURL(file);
$('#img').attr('src', url);
})
再看看toDataURL()
方法
它的使用方法和toBlob
類似,不過最后生成的是base64的二進(jìn)制碼,可以將其傳至后臺(tái)做圖片存儲(chǔ)用
img.onload = function() {
ctx.drawImage(img, 0, 0);
var dataURL = canvas.toDataURL();
console.log(dataURL);//data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAfQA...省略一堆字符串
}
這里沒法轉(zhuǎn)input上傳的圖片
最后看看getImageData()
這個(gè)方法獲取到一個(gè)指定范圍(x,y,寬,高)的像素信息,這里不詳細(xì)介紹,只要知道這個(gè)方法也是沒法獲取受污染畫布的信息的
參考文件
FileReader() https://developer.mozilla.org/zh-CN/docs/Web/API/FileReader
toBlob() https://developer.mozilla.org/zh-CN/docs/Web/API/HTMLCanvasElement/toBlob
toDataURL() https://developer.mozilla.org/zh-CN/docs/Web/API/HTMLCanvasElement/toDataURL
getImageData() https://developer.mozilla.org/zh-CN/docs/Web/API/CanvasRenderingContext2D/getImageData
啟用了 CORS 的圖片 https://developer.mozilla.org/zh-CN/docs/Web/HTML/CORS_enabled_image