【串連】
本文轉自豆瓣社區http://www.douban.com/note/225494734/
1、http://www.html5rocks.com/en/tutorials/webgl/typed_arrays/
這篇寫得比我好。
2、至於一些很方便庫,可以直接看aurora.js這個項目,為瞭解析音頻檔案,這個項目下了很大功夫...
https://github.com/ofmlabs/aurora.js
【前言】
JS其實是眾所周知的弱類型語言。所以一般來說不屬於嚴肅編程領域,直到近年才受到關注,WEB 2.0以及很多新技術的興起。把它抬上了嚴肅編程的範疇。
這裡主要記錄最近碰到的JS,學術一些來說應該說是EMSCRIPT標準、W3C、HTML5、GOOGLE推出的一系列,對這個語言庫層級的改進。
對二進位的需求與日俱增的原因如下:WEBSCOKET的傳輸需求,FILE API對檔案、二進位BLOB對象的處理,WEBGL對於大量位元據的需求,CAVANS對二進位的處理的迫切需求、XHR2對新的二進位對象的處理需求,也會敘述與NODE.JS的二進位有關的事宜。
*PS:強烈建議去閱讀原草案,以及標準文檔,當然這裡會給出草案的地址
【目錄】
一、XHR2
二、FILE API
1、FILE LIST
2、FILE
3、FILEREADER
三、BLOB URL
四、TYPED ARRAY
1、BUFFER
2、ArrayView
3、DataView
4、Blob 與 arraybuffer
5、arraybuffer 與 arraybufferView
五、WEBSCOKET
六、WEBGL
【XHR2】
http://www.html5rocks.com/en/tutorials/file/xhr2/
http://www.w3.org/TR/XMLHttpRequest/#the-responsetype-attribute
新的XHR2文法上有很多改進,細節部分不詳述,可以參見草案。
//得到某個檔案的串列
vargetArrayBuffer=function(url){
var resourceUrl = url || "http://img1.douban.com/pics/nav/lg_main_a10.png";
var deferred = $.Deferred();
var promise = deferred.promise();
var xhr = new XMLHttpRequest();
xhr.open('GET', resourceUrl, true);
// Response type arraybuffer - XMLHttpRequest 2
xhr.responseType = 'arraybuffer';
xhr.onerror = function(e) {
deferred.reject(xhr, e);
}
xhr.onload = function(e) {
if (xhr.status == 200) {
deferred.resolve(xhr);
}
};
xhr.send();
return promise;
}
這裡使用了JQ的defferd對象,可以無視,主要修改在於返回xhr.responseType可以設定成arraybuffer或者blob。
【FILE API】
1、主要有File List來表述任何<input type='file'>裡的對象,File繼承與Blob父類,對了長度以及檔案名稱屬性,繼承了Slice操作。
2、File表述一個<input type=file>裡的檔案對象,注意,這裡的File似乎必須是來自於使用者輸入,暫時沒有找到憑空構造的方式。
3、Blob對象是File的父類,主要會感興趣的操作為Slice,分割操作。
4、FileReader()讀寫類,主要負責File|Blob對象的讀寫
http://www.w3.org/TR/FileAPI/#readAsDataURL
var loadBlobToBase64=function(blob){
var deferred = $.Deferred();
var promise = deferred.promise();
var reader = new FileReader();
reader.onload = function() {
deferred.resolve(reader.result);
}
reader.readAsDataURL(blob);
return promise;
}
比較有用的操作為將File或Blob對象讀寫成為BASE64編碼的DataURL,readAsText(),以及readAsArrayBuffer()
【URL API/BLOB URI】
http://www.w3.org/TR/FileAPI/#url
這個理解起來較為簡單,在標準裡,也位於FILE API草案中描述。
var url=window.webkitURL.createObjectURL(blob);
console.log(url);
輸出為:blob:xxxx-xxx-xxx--xxx#frament...
簡單得說就是,你可以使用File API中的FileReader()類,將檔案或二進位的大塊Blob,readAsDataURL,然後賦予img src或其他。
也可以將blob轉儲為BLOB URL,官方的表述即ObjectURL
怎樣理解?
這個URL,是一個記憶體級的指標,但可以供網頁調用,其行為與普通的來自伺服器的檔案毫無二致。
有200狀態代碼,也有500狀態代碼,可以銷毀。
【Typed Array】
http://www.khronos.org/registry/typedarray/specs/latest/
這是這整一套API的核心部分,事實上,不理解這部分,就很難對資料進行任何有效操作與轉換。
暫時以我的理解來說。
1、Buffer
http://www.khronos.org/registry/typedarray/specs/latest/#5
var a=new ArrayBuffer(8);
建立一個新的ArrayBuffer(8);,8bit位為一個單位,uint8。我要了8個單位,即位元組。
這是一個記憶體層級的表達,一個buf.
2、View
http://www.khronos.org/registry/typedarray/specs/latest/#7
appendBuffer=function ( buffer1, buffer2 ) {
var tmp = new Uint8Array( buffer1.byteLength + buffer2.byteLength + 4);
tmp.set( new Uint8Array( buffer1 ), 0 );
tmp.set( new Uint8Array( buffer2 ), buffer1.byteLength );
return tmp;
}
new Uint8Array實際上是建立了一個ref,指標。它可以指向一個已有的buf,那麼這裡建立了一個tem,其大小為兩個buf之和+4.
第二句話是,從0位移量開始,填入一個新的Typed ArrayView ,而這個指標是以buffer1初始化的。
第三句,是從剛才的結尾開始,填入buffer2的內容。
這裡待修改。
3、DataView
http://www.khronos.org/registry/typedarray/specs/latest/#8
https://developer.mozilla.org/en/JavaScript_typed_arrays/DataView
暫略
4、Blob 與 arraybuffer
http://www.w3.org/TR/FileAPI/#dfn-BlobPropertyBag
著名的文章,構造BLOB,別BUILD,指之前一個非廢止的API ,Blobuilder。那個方法效率很低,而且容易出錯(我就寫JS寫出藍屏...過....)
所以,正確的構造法為:
var blob = new Blob([new_buffer], { type: "image/png" });
傳入一個ArrayBuffer對象,並給出MIME TYPE之後,就可以構造恰當的對象。
var url = window.webkitURL.createObjectURL(blob);
接著可以用剛才提到的方式,構造BLOB URL,以供<img src>來調用。
5、arraybuffer 與 arraybufferView
http://www.khronos.org/registry/typedarray/specs/latest/#6
這個當初也讓我迷惑了一陣子,直到看到草案上的複雜資料結構的一個例子之後才理解了。
簡單的說:
appendBuffer=function ( buffer1, buffer2 ) {
var tmp = new Uint8Array( buffer1.byteLength + buffer2.byteLength + 4);
tmp.set( new Uint8Array( buffer1 ), 0 );
tmp.set( new Uint8Array( buffer2 ), buffer1.byteLength );
return tmp;
}
剛才的例子裡,返回的這個tmp,實際上是一個arraybufferView對象,而非buffer本身。
在構造新的BLOB時發現的,所有的Uin8Array對象,都會有一個屬性,即buffer屬性。
要得到指標指的對象的內容,訪問這個屬性即可。
var blob = new Blob([tmp.buffer], { type: "image/png" });
如果你要操作tmp,並構造成BLOB對象,直接用arrayBuffer就可以了,如果傳入的是一個TypedArrayView?,也不用著急,訪問其.buffer屬性即得到背後的ArrayBuffer屬性。