Blob

来源:互联网 发布:java程序员年终总结 编辑:程序博客网 时间:2024/05/20 15:10

    Blob(Binary Large Object)术语最初来自数据库,早期数据库因为要存储声音、图片、以及可执行程序等二进制数据对象所以给该类对象取名为Blob
    在Web领域,Blob被定义为包含只读数据的类文件对象。Blob中的数据不一定是js原生数据形式。常见的File接口就继承自Blob,并扩展它用于支持用户系统的本地文件。

    构建一个Blob对象通常有三种方式:1、通过Blob对象的构造函数来构建。2、从已有的Blob对象调用slice接口切出一个新的Blob对象。3、canvas API toBlob方法,把当前绘制信息转为一个Blob对象。下面分别看看3种方式的实现:


构造函数:
var blob = new Blob(array[optional], options[optional]);

array(可选): 一个数组。数组元素可以是:ArrayBufferArrayBufferViewBlobDOMString.或者他们的组合。
options(可选): 一个对象。用于指定Blob对象的属性,可选的参数有:
type: Content-Type,用于指定将要放入Blob中的数据的类型(MIME)。


Blob对象的基本属性:

size : Blob对象包含的字节数。(只读)
type : Blob对象包含的数据类型MIME,如果类型未知则返回空字符串。


Blob对象的基本方法:
Blob.slice([start, [end, [content-type]]])

slice方法与数组的slice类似。


原生对象构建Blob

<script type="text/javascript">window.onload = function() {    var blob = new Blob(1234);}</script>

提示出错:

Uncaught TypeError: Failed to construct ‘Blob’: The 1st argument is neither an array, nor does it have indexed properties.

原因在于Blob构造函数要求第一个参数必须是数组,而这里第一个参数既不是一个数组,也没有可索引的属性。既然这里提到了对象的可索引属性,让我联想到了类数组的概念,而Arguments就是一个很好的例子。来试一试:

<script type="text/javascript">function testArgumentsBlob() {    var blob = new Blob(arguments);    console.log(blob.size);//3    console.log(blob.type);//""}window.onload = function() {    testArgumentsBlob(1, 2, 3);}</script>

可以看到即使是类数组对象,而数组元素类型是Number也能得出正确的结论,猜想大概是由于构造函数内部把Number转化为String的缘故吧!

再来试一试其他的参数类型:

window.onload = function() {  var arg = {hello: "2016"};  var blob = new Blob([JSON.stringify(arg, null, "\t")], {type: "application/json"});  console.log(blob.type);//application/json  console.log(blob.size);//20}

blob.type等于application/json没问题。arg转为字符串后的长度为16加上制表符\t的宽度4个字节等于20。


slice切出一个Blob对象

window.onload = function() {    var arg = {hello: "2016"};    var str = JSON.stringify(arg, null, "\t");    var blob = new Blob([str], {type: "application/json"});    var blob2 = blob.slice();    console.log(blob2.size);//20    console.log(blob2.type);//""}

可以看到,原始的Blob对象的type属性并不能传递给新的Blob对象,所以还是要自己指定。

window.onload = function() {    var arg = {hello: "2016"};    var str = JSON.stringify(arg, null, "\t");    var blob = new Blob([str], {type: "application/json"});    var blob2 = blob.slice(0, blob.size, "application/json");    console.log(blob2.size);//20    console.log(blob2.type);//application/json}

canvas toBlob接口

函数原型:

void canvas.toBlob(callback, type, encoderOptions);

  • callback: 一个回调函数,新建的blob对象是唯一的参数`
  • type: 图片格式,默认为image/png,默认dpi: 96
  • encoderOptions: 0~1之间的数值。当type为image/jpeg 或 image/webp的时候,用于指定图片质量

来个DEMO:

window.onload = function() {    var canvas = document.getElementById("main");    canvas.toBlob(function(blob) {        var img = document.createElement("img");                 var url = URL.createObjectURL(blob);        img.onload = function() {            URL.revokeObjectURL(url);        }        img.src = url;        document.body.appendChild(img);    });}</script>

得出错误:

Uncaught TypeError: canvas.toBlob is not a function.

一开始觉得自己写错了,Google了下才发现Chrome居然不支持这个接口。给个polyfillCanvas toBlob。


Blob基本运用

知道了Blob对象的基本属性,以及构建的方法,来看几个具体的运用。


利用Blob显示对象`

var blob = new Blob([1, 2, 3]);var src = URL.createObjectURL(blob);console.log(src);//blob:http%3A//localhost%3A8003/a47ea163-c253-471a-9d9e-877fe345b60fvar img = document.createElement('img');img.onload = function() {    URL.invokeObjectURL(img.src);}img.src = src;document.body.appendChild(img);

由于blob对象不是一个有效的文件,所以不能正常显示图片。上面的demo提到了一个URL.createObjectURL接口,顺便来学习以下:

objectURL = URL.createObjectURL(blob);

主要用于根据一个Blob对象(或者File,因为File继承自Blob),创建一个URL用于表示该对象。需要注意的是即使对同一个对象调用两次也会得到不同的URL。如果该URL不用了需要调用URL.invokeObjectURL来进行释放。浏览器会在当前document unloaded的时候自动把该URL释放。URL格式:

blob:http%3A//localhost%3A8003/a47ea163-c253-471a-9d9e-877fe345b60f

最后来看一个正常点的DEMO,利用URL.createObjectURL读取本地图片文件,并创建缩略图。


利用Blob显示缩略图`

 var input = document.createElement("input"); input.type = "file"; input.accept = "image/*"; input.multiple = true; input.style.display = "none"; document.body.appendChild(input); var fileSelect = document.createElement("a"); fileSelect.href = "#"; fileSelect.appendChild(document.createTextNode("Choose files")); document.body.appendChild(fileSelect); var imgList = document.createElement("div"); imgList.innerHTML = "<p>No file Selected!</p>" document.body.appendChild(imgList); input.addEventListener("change", function(e) { var files = this.files; if(!files.length) {    return; } imgList.innerHTML = ""; var list = document.createElement("ul"); imgList.appendChild(list); for(var i = 0; i < files.length; i++) {     var li = document.createElement("li");      list.appendChild(li);     var img = document.createElement("img");     img.src = window.URL.createObjectURL(files[i]);     img.height = 60;     img.width  = 60;     img.onload = function() {         window.URL.revokeObjectURL(this.src);     }     li.appendChild(img);     var info = document.createElement("span");     info.innerHTML = files[i].name + ":" + files[i].size + " bytes";     li.appendChild(info);  }}, false);fileSelect.addEventListener("click", function(e) {  input.click();            e.preventDefault();}, false);

由于File对象继承自Blob,所以我们可以很方便的利用File对象加载本地系统图片文件,并通过createObjectURL生成一个URL并加以显示。

参考文献:
+ Blob
+ Using_files_from_web

0 0
原创粉丝点击