關於DataURL Blob File FileReader createObjectURL canvas及其相互轉化
標籤(空格分隔): js文件處理
關於DataURL Blob File FileReader createObjectURL canvas及其相互轉化
DataURL
傳統的img標籤是通過引入服務器上的圖片資源,瀏覽器對每個這樣的img標籤都會向服務器發送一個請求,一個頁面中有過多的這種外部資源會導致頁面的加載延遲。
而dataurl
是把資源文件的內容轉換成base64編碼字符串,直接把編碼放到src屬性裏就和一個引用外部資源一樣使用了,這樣dataurl
可以用來優化網站加載速度,特別是html中有大量外部資源引用的時候
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAJYAAABVCAYAAACrfR34AAANXklEQ…zeoA3eFaDbhy7ZoppkoWbcQusOKWBlNlndwHIspuo7WP8A9S1SD+cdaTAAAAAASUVORK5CYII=" />
這是上面圖片的效果
DataURL的問題
- 資源文件轉換成base64編碼文件大小會變爲原來的4/3
- Data URL形式的圖片不會被瀏覽器緩存
CSS中使用DataURL(base64編碼可以放在url內使用)
background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAJYAAABVCAYAAACrfR34AAANXklEQ…zeoA3eFaDbhy7ZoppkoWbcQusOKWBlNlndwHIspuo7WP8A9S1SD+cdaTAAAAAASUVORK5CYII=");
Blob
一個
Blob
對象就是一個包含有隻讀原始數據的類文件對象,包含的是二進制的數據,File就是基於Blob的接口
屬性
屬性名 | 描述 |
---|---|
size | blob對象中包含的數據大小 |
type | blob對象中包含的數據的MIME類型(只讀) |
使用方法
//創建Blob對象
var html = "<p>萌新瑟瑟發抖</p>";
var htmlBlob = new Blob([html],'text/xml');
//第一個參數是數據內容,必須寫成數組的形式,第二個參數是數據的類型
Blob對象方法
slice()
用來獲取Blob對象中指定範圍內的數據,返回新的Blob對象
參數名 | 描述 |
---|---|
start(可選) | 指定要獲取的部分的開始位置(默認爲0) |
end(可選) | 指定要獲取的部分的結束位置(默認爲最後) |
contentType(可選) | 返回的Blob對象的數據類型(默認爲空字符串) |
File
File
是基於Blob
的接口,創建方法類似。
屬性
屬性名 | 描述 |
---|---|
name | File對象的名稱(文件名) |
lastModified | File對象最後一次修改時間 |
size | File對象中包含的數據大小 |
type | File對象中包含的數據的MIME類型(只讀) |
使用方法
//創建File對象
var html = "<p>萌新瑟瑟發抖</p>";
var htmlFile = new File([html],'text/xml');
//第一個參數是數據內容,必須寫成數組的形式,第二個參數是數據的類型
File
對象可以從<input type='file' />
獲取
下面是html代碼
<input type='file' id='file1' />
下面是js代碼
var file1 = document.getElementById('file1').files[0];
//這裏的file1就是一個File對象
FileReader
FileReader 可以異步的讀取計算機上的文件或者是瀏覽器的緩存,數據來源可以是
<input type='file' />
標籤,也可以是html中的img標籤等,或者是canvas的mozGetAsFile()
方法返回的結果
創建方法
var fr = new FileReader();
readyState取值
狀態名 | 值 | 描述 |
---|---|---|
EMPTY | 0 | 讀取文件時發生錯誤(只讀) |
LOADING | 1 | 指的是讀取文件完成或者被中止時的狀態(只讀) |
DONE | 2 | 指示已經完成了文件的讀取 |
屬性
屬性名 | 描述 |
---|---|
error | 讀取文件時發生錯誤(只讀) |
readyState | 指的是讀取文件完成或者被中止時的狀態(只讀) |
result | FileReader對象讀取文件完成後返回的,只有在讀取完成後纔有效,readAsArrayBuffer()、readAsDataURL()、readAsBinaryString()三個讀取文件的方法都會返回result,但是數據類型不同(只讀) |
方法
abort()
立即結束讀取操作,並返回相應數據,這時readyState值爲DONE
readAsArrayBuffer()
開始讀取指定的Blob或File對象中的內容. 當讀取操作完成時,readyState屬性的值會成爲DONE,如果設置了onloadend事件處理程序,則調用之.同時,result屬性中將包含一個ArrayBuffer對象以表示所讀取文件的內容
參數
參數名 | 描述 |
---|---|
blob/file | 一個Blob或File對象 |
var aBuf = fr.readAsArrayBuffer(file1);
readAsBinaryString()
開始讀取指定的Blob或File對象中的內容. 當讀取操作完成時,readyState屬性的值會成爲DONE,如果設置了onloadend事件,就調用它.同時,result屬性中將包含讀取的文件的二進制數據
readAsDataURL()
開始讀取指定的Blob或File對象中的內容. 當讀取操作完成時,readyState屬性的值會成爲DONE,如果設置了onloadend事件,就調用它.同時,result屬性中將包含一個DataURL格式的字符串來表示所讀取文件的內容
readAsText()
開始讀取指定的Blob或File對象中的內容. 當讀取操作完成時,readyState屬性的值會成爲DONE,如果設置了onloadend事件,就調用它.同時,result屬性中將包含一個字符串來表示所讀取文件的內容
(後面這兩種方法和readAsArrayBuffer的參數及使用方式都相同)
createObjectURL
這個方法是window.URL中的一個方法,可以返回一個DataURL字符串,瀏覽器支持也比較好,相應的有釋放的方法revokeObjectURL
參數
參數名 | 描述 |
---|---|
file/blob | File或者Blob對象 |
使用方法
var dataUrl = window.URL.createObjectURL(file1);
window.URL.createObjectURL(dataurl);
canvas之toDataURL和toBlob函數
這裏並不是要詳細講解canvas(畢竟博大精深,萌新根本不懂2333),只是簡單介紹canvas 的 toDataURL和toBlob方法
toDataURL()
var img = new Image();
img.src = dataUrl;
var canvas = document.createElement('canvas');
var ctx = canvas.getContext();
ctx.drawImage(img,sx,sy,swidth,sheight,width,height);
var dataUrl1 = canvas.toDataURL();
//這裏的dataUrl1就是這個canvas所繪製的這部分圖像的數據
toBlob()
參數
參數名 | 描述 |
---|---|
callback | 回調函數做參數,當轉換完成時就調用這個回調函數 |
type | 指定的返回的Blob對象的type值,即MIME類型,默認爲image/png |
使用方法
var blob1;
var blob = canvas.toBlob(function(blob){
blob1 = blob;
},'image/png');
//這裏的blob1就是這個canvas所繪製的這部分圖像的數據
相互轉換
這裏是總結一下Blob/File對象與DataURL、canvas之間的轉換,也包括了FileReader和createObjectURL的使用
canvas與DataURL
//就用前面代碼中創建的canvas來做演示
//canvas > DataURL
var dataurl = canvas.toDataURL();//可選參數type,定義dataurl中的數據類型,默認爲'image/png';
//DataURL > canvas
//先要把DataURL寫入一個Image對象中,然後用canvas來繪製
var img = new Image();//創建Image對象
var canvas1 = document.createElement('canvas');//創建canvas
var ctx = canvas1.getContext('2d');
img.onload = function(){
ctx.drawImage(img,0,0);
}//這個onload是在image對象加載數據完成後調用
img.src = dataurl;
Blob/File 與 DataURL
//DataURL > Blob/File
//假定現在有一個dataurl,現在直接封裝一個dataURLToBlob函數
function dataURLToBlob(dataurl){
var arr = dataurl.split(',');
var mimeType = arr[0].match(/:(.*?);/)[1];
var mainData = arr[1];//這裏的數據是一個base64編碼的字符串,下面要進行解碼才能傳給Blob;
//這裏要用到atob函數將base64編碼數據解碼(當然也有對應的btoa函數將數據編碼成base64數據)
var originData = atob(mainData);
return new Blob([originData],mimeType);
}
//Blob/File > DataURL
//這個轉換需要FileReader的參與,假定現在有一個file/blob對象可用
var dataurl;
var fr = new FileReader();
fr.onload = function(){
dataurl = fr.result;
}
fr.readAsDataURL(file/blob);
Blob/File 與 canvas
//canvas > Blob/File
//假定現在有一個canvas
var blob;
canvas.toBlob(function(blob){
blob = blob;
},'image/png');
//Blob/File > canvas
//這個轉換需要FileReader的參與,假定現在有一個file/blob對象可用
var dataurl;
var img = new Image();
var fr = new FileReader();
fr.onload = function(){
dataurl = fr.result;
img.src = dataurl;
}
img.onload = function(){
ctx.drawImage(img,0,0);
}
fr.readAsDataURL(file/blob);