記得以前做網站時,曾經需要實現一個圖片上傳到服務器前,先預覽的功能。當時用html的<input type="file"/>標簽一直實現不了,最后舍棄了這個標簽,使用了其他方式來實現了這個功能。
今天無意發現了一個知識點,用html的file標簽就能實現圖片上傳前預覽,感覺很棒,記錄一下!就是通過file標簽和js的FileReader接口,把選擇的圖片文件調用readAsDataURL方法,把圖片數據轉成base64字符串形式顯示在頁面上。
1、閑話少說,測試一下,圖片上傳前預覽(選擇圖片):
實現代碼:
<div style="border:2px dashed red;">
<p>
圖片上傳前預覽:<input type="file" id="xdaTanFileImg" onchange="xmTanUploadImg(this)" accept="image/*"/>
<input type="button" value="隱藏圖片" onclick="document.getElementById('xmTanImg').style.display = 'none';"/>
<input type="button" value="顯示圖片" onclick="document.getElementById('xmTanImg').style.display = 'block';"/>
</p>
<img id="xmTanImg"/>
<div id="xmTanDiv"></div>
</div>
<hr />
<script type="text/javascript">
//判斷瀏覽器是否支持FileReader接口
if (typeof FileReader == 'undefined') {
document.getElementById("xmTanDiv").InnerHTML = "<h1>當前瀏覽器不支持FileReader接口</h1>";
//使選擇控件不可操作
document.getElementById("xdaTanFileImg").setAttribute("disabled", "disabled");
}
//選擇圖片,馬上預覽
function xmTanUploadImg(obj) {
var file = obj.files[0];
console.log(obj);console.log(file);
console.log("file.size = " + file.size); //file.size 單位為byte
var reader = new FileReader();
//讀取文件過程方法
reader.onloadstart = function (e) {
console.log("開始讀取....");
}
reader.onprogress = function (e) {
console.log("正在讀取中....");
}
reader.onabort = function (e) {
console.log("中斷讀取....");
}
reader.onerror = function (e) {
console.log("讀取異常....");
}
reader.onload = function (e) {
console.log("成功讀取....");
var img = document.getElementById("xmTanImg");
img.src = e.target.result;
//或者 img.src = this.result; //e.target == this
}
reader.readAsDataURL(file)
}
</script>
------------------------------- end -----------------------------
2、另外 FileReader除了有函數readAsDataURL,另外還有另外兩個函數readAsBinaryString 和 readAsText,分別可以將選擇的文件讀取成二進制和文本格式
測試一下,選擇文本(txt、cs、html、js、css、xml),讀取成二進制或者文本:
實現代碼:
<script type="text/javascript">
//判斷瀏覽器是否支持FileReader接口
if (typeof FileReader == 'undefined') {
document.getElementById("xmTanContentDiv").InnerHTML = "<p>當前瀏覽器不支持FileReader接口!</p>";
document.getElementById("xmTanFile").setAttribute("disabled", "disabled");
}
//選擇文件
function xmTanUploadFile(obj){
if (obj.files.length < 1) return;
var file = obj.files[0];
if (file.size > 1024 * 1024) {
alert("文件大於1M, 太大了,小點吧!");
obj.value = "";
return;
}
}
//讀取文件為二進制
function readAsBinaryString() {
var obj = document.getElementById("xmTanFile");
if (obj.files.length < 1) return;
var file = obj.files[0];
var reader = new FileReader();
//將文件以二進制形式讀入頁面
reader.readAsBinaryString(file);
reader.onload = function (f) {
document.getElementById("xmTanContentDiv").innerHTML = this.result;
}
}
//讀取文件為文本
function readAsText() {
var obj = document.getElementById("xmTanFile");
if (obj.files.length < 1) return;
var file = obj.files[0];
var reader = new FileReader();
//將文件以文本形式讀入頁面
reader.readAsText(file);
reader.onload = function (f) {
document.getElementById("xmTanContentDiv").innerHTML = this.result;
}
}
</script>
<div style="border: 2px dashed red; padding: 20px 0px;">
<label>選擇文件:</label>
<input type="file" id="xmTanFile" accept=".html,.js,.css,.txt,.cs,.xml" onchange="xmTanUploadFile(this)"/>
<input type="button" value="讀取成二進制數據" onclick="readAsBinaryString()" />
<input type="button" value="讀取成文本數據" onclick="readAsText()" />
<input type="button" value="隱藏讀取內容" onclick="document.getElementById('xmTanContentDiv').style.display = 'none';"/>
<input type="button" value="顯示讀取內容" onclick="document.getElementById('xmTanContentDiv').style.display = 'block';"/>
<div id="xmTanContentDiv"></div>
</div>
---------------------------
3、----------- a標簽之download屬性 -------------
設置a標簽href為圖片鏈接,再設置download屬性,點此鏈接可以直接下載圖片

點此下載
實現代碼:
<div style="text-align:center; padding: 5px 20px;width: 70%;">
<img id="xmTanShowImg" src=""/>
<h1><a href="javascript:void()" download="girl.jpg" id="xmTanDownload">點此下載</a></h1>
</div>
<script type="text/javascript">
//圖片轉成base64位字符串數據
var imgData = "data:image/png;base64,.......";
//或直接設置圖片鏈接: var imgData = "images/girl.png"; //設置圖片鏈接時,如果圖片和頁面在同一個網站,直接設置即可;如果圖片和頁面不在同一個域名,服務器需要處理跨域問題,否則會報錯
document.getElementById("xmTanShowImg").setAttribute("src", imgData); //給圖片標簽設置src
document.getElementById("xmTanDownload").setAttribute("href", imgData); //給a標簽設置href
</script>
4、網絡圖片(完整圖片地址)轉base64和文件流 (2018-11-01 add )
突然有這個需求:要求把裁剪后的圖片(返回一個網絡地址)以文件流的方式上傳到服務器。
因此需要把一個網絡圖片轉成base64, 再轉成文件流格式:
//傳入圖片地址,獲取圖片Base64數據 function getBase64ByImgUrl(url, callback){ var canvas = document.createElement('canvas'), ctx = canvas.getContext('2d'), img = new Image; img.crossOrigin = 'Anonymous'; img.onload = function(){ canvas.height = img.height; canvas.width = img.width; ctx.drawImage(img,0,0); var dataURL = canvas.toDataURL('image/png'); console.log('base64-dataUrl: ', dataURL); callback(dataURL); canvas = null; }; img.src = url; } //將base64轉換為文件流 function getFileByBase64(dataurl, filename) { var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1], bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n); while(n--){ u8arr[n] = bstr.charCodeAt(n); } return new File([u8arr], filename, {type:mime}); } //測試 var url = 'https://images2015.cnblogs.com/blog/454511/201601/454511-20160131134129224-636191193.png'; getBase64ByImgUrl(url, function(dataURL){ //傳入base64數據和文件名字 var fileFlow = getFileByBase64(dataURL, 'imgName' + (new Date()).getTime()); console.log('fileFlow: ', fileFlow); //繼續.... })
