js二进制数据,文件---blob对象

blob

Blob 由一个可选的字符串 type(通常是 MIME 类型)和 blobParts 组成 —— 一系列其他 Blob 对象,字符串和 BufferSource,blob就是具有类型的二进制数据

MIME 类型 

MIME (Multipurpose Internet Mail Extensions) 是描述消息内容类型的标准,用来表示文档、文件或字节流的性质和格式。

MIME 消息能包含文本、图像、音频、视频以及其他应用程序专用的数据。

更多关于MIME 类型 可以参考 MIME 类型

常见的 MIME 类型

  • 超文本标记语言文本 .html、.html:text/html

  • 普通文本 .txt: text/plain

  • RTF 文本 .rtf: application/rtf

  • GIF 图形 .gif: image/gif

  • JPEG 图形 .jpeg、.jpg: image/jpeg

  • au 声音文件 .au: audio/basic

  • MIDI 音乐文件 mid、.midi: audio/midi、audio/x-midi

  • RealAudio 音乐文件 .ra、.ram: audio/x-pn-realaudio

  • MPEG 文件 .mpg、.mpeg: video/mpeg

  • AVI 文件 .avi: video/x-msvideo

  • GZIP 文件 .gz: application/x-gzip

  • TAR 文件 .tar: application/x-tar

构造blob对象

Blob 构造器允许从几乎任何东西创建 blob

let blob = new Blob([],{});

参数1:数组, 内部存放Blob/BufferSource/String 类型的值。

参数2:对象(可选),

  • type —— 指定Blob 对象的类型,通常是 MIME 类型,例如 image/png
  • endings —— 是否转换换行符,使 Blob 对应于当前操作系统的换行符(\r\n 或 \n)。默认为 "transparent"(啥也不做),不过也可以是 "native"(转换)。

构造一个文本类的blob对象

let hello = new Uint8Array([72, 101, 108, 108, 111]); // 二进制格式的 "hello"
let blob = new Blob([hello,"world"],{type:"text/plain"});

console.log(blob);

这里表示长度为10的txt文本

 slice 方法来提取 Blob 片段:

blob.slice([byteStart], [byteEnd], [contentType]);
  • byteStart —— 起始字节,默认为 0。
  • byteEnd —— 最后一个字节(不包括,默认为最后)。
  • contentType —— 新 blob 的 type,默认与源 blob 相同。

参数值类似于 array.slice,也允许是负数。

let sliceBlob = blob.slice(0,5,"text/plain");
console.log(sliceBlob);

 

Blob 对象是不可改变的

        我们无法直接在 Blob 中更改数据,但我们可以通过 slice 获得 Blob 的多个部分,从这些部分创建新的 Blob 对象,将它们组成新的 Blob,等。例如,blob可能表示一张图片,我们并不能改变这张原图片,这就像字符串的一些方法并不改变原字符串那样。

blob用作url

blob是二进制数据,直接打印并不直观,我们可以通过<a><img> 或其他标签的 URL,来显示它们的内容。

<a download="hello.txt" href='#' id="link">Download</a>
document.getElementById("link").href = URL.createObjectURL(blob);

 利用a标签的download属性和URL的方法将blob对象转成url并下载

 

 可以看到blob里面存放的是一个txt类型的文本数据,内容是helloworld

URL.createObjectURL 取一个 Blob,并为其创建一个唯一的 URL,形式为 blob:<origin>/<uuid>

blob:源网页地址,特定的id码

 

我们可以看到a标签的href属性就是一个blob url

blob url只允许在源网页使用,而且具有临时性,仅在当前文档打开的状态下才有效。

        浏览器内部为每个通过 URL.createObjectURL 生成的 URL 存储了一个 URL → Blob 映射。虽然这里有 Blob 的映射,但Blob 本身只保存在内存中的。浏览器无法释放它。如果我们创建一个 URL,那么即使我们不再需要该 Blob 了,它也会被挂在内存中。URL.revokeObjectURL(url) 从内部映射中移除引用,因此允许 Blob 被删除(如果没有其他引用的话),并释放内存。

blob转base64 (data-url)

Blob 转换为 base64-编码的字符串。这种编码将二进制数据表示为一个由 0 到 64 的 ASCII 码组成的字符串,非常安全且“可读“。更重要的是 —— 我们可以在 “data-url” 中使用此编码。

“data-url” 的形式为 data:[<mediatype>][;base64],<data>。我们可以在任何地方使用这种 url,和使用“常规” url 一样。

<img src="data:image/png;base64,R0lGODlhDAAMAKIFAF5LAP/zxAAAANyuAP/gaP///wAAAAAAACH5BAEAAAUALAAAAAAMAAwAAAMlWLPcGjDKFYi9lxKBOaGcF35DhWHamZUW0K4mAbiwWtuf0uxFAgA7">

let reader = new FileReader();
reader.readAsDataURL(blob); // 将 Blob 转换为 base64 并调用 onload

reader.onload = function() {
  link.href = reader.result; // data url
};

这部分的作用和blob url 的效果一样

image图片转blob 

我们可以创建一个图像(image)的、图像的一部分、或者甚至创建一个页面截图的 Blob。这样方便将其上传至其他地方。

图像操作是通过 <canvas> 元素来实现的:

  1. 使用 canvas.drawImage 在 canvas 上绘制图像(或图像的一部分)。
  2. 调用 canvas 方法 .toBlob(callback, format, quality) 创建一个 Blob,并在创建完成后使用其运行 callback
// 获取任何图像
let img = document.querySelector('img');

// 生成同尺寸的 <canvas>
let canvas = document.createElement('canvas');
canvas.width = img.clientWidth;
canvas.height = img.clientHeight;

let context = canvas.getContext('2d');

// 向其中复制图像(此方法允许剪裁图像)
context.drawImage(img, 0, 0);
// 我们 context.rotate(),并在 canvas 上做很多其他事情

// toBlob 是异步操作,结束后会调用 callback
canvas.toBlob(function (blob) {
    // blob 创建完成,下载它
    let link = document.createElement('a');
    link.download = 'example.png';

    link.href = URL.createObjectURL(blob);
    link.click();

    // 删除内部 blob 引用,这样浏览器可以从内存中将其清除
    URL.revokeObjectURL(link.href);
}, 'image/png');

这样当页面加载后会直接下载img图片

blob和 ArrayBuffer ,stream

我们可以从 blob.arrayBuffer() 中获取最低级别的 ArrayBuffer

 关于ArrayBuffer--- js二进制数据,文件---ArrayBuffer,二进制数组-CSDN博客

blob.arrayBuffer().then(buffer =>{
     /* 处理 ArrayBuffer */
    console.log(buffer);
});

Blob 接口里的 stream() 方法返回一个 ReadableStream,在被读取时可以返回 Blob 中包含的数据。 

// 从 blob 获取可读流(readableStream)
const readableStream = blob.stream();
const stream = readableStream.getReader();

(async()=>{
    while (true) {
        // 对于每次迭代:value 是下一个 blob 数据片段
        let { done, value } = await stream.read();
        if (done) {
            // 读取完毕,stream 里已经没有数据了
            console.log('all blob processed.');
            break;
        }

        // 对刚从 blob 中读取的数据片段做一些处理
        console.log(value);
    }
})()

总结

blob是具有类型的二进制数据

Blob 在浏览器中常用于上传/下载操作

XMLHttpRequestfetch 等进行 Web 请求的方法可以自然地使用 Blob,二进制数据传递效率最高

  • 我们可以使用 new Blob(...) 构造函数从一个类型化数组(typed array)创建 Blob
  • 我们可以使用 blob.arrayBuffer() 从 Blob 中取回 arrayBuffer,然后在其上创建一个视图(view),用于低级别的二进制处理。

完整代码展示

为了不影响结果展示,部分代码被注释

// blob.js
let hello = new Uint8Array([72, 101, 108, 108, 111]); // 二进制格式的 "hello"
let blob = new Blob([hello, "world"], { type: "text/plain" });
console.log(blob);

let sliceBlob = blob.slice(0, 5, "text/plain");
console.log(sliceBlob);

document.getElementById("link").href = URL.createObjectURL(blob);
// let reader = new FileReader();
// reader.readAsDataURL(blob); // 将 Blob 转换为 base64 并调用 onload

// reader.onload = function() {
//     link.href = reader.result; // data url
// };

// 获取任何图像
let img = document.querySelector('img');

// 生成同尺寸的 <canvas>
let canvas = document.createElement('canvas');
canvas.width = img.clientWidth;
canvas.height = img.clientHeight;

let context = canvas.getContext('2d');

// 向其中复制图像(此方法允许剪裁图像)
context.drawImage(img, 0, 0);
// 我们 context.rotate(),并在 canvas 上做很多其他事情

// toBlob 是异步操作,结束后会调用 callback
canvas.toBlob(function (blob) {
    // blob 创建完成,下载它
    let link = document.createElement('a');
    link.download = 'example.png';

    link.href = URL.createObjectURL(blob);
    // link.click();// 触发a标签点击事件

    // 删除内部 blob 引用,这样浏览器可以从内存中将其清除
    URL.revokeObjectURL(link.href);
}, 'image/png');

blob.arrayBuffer().then(buffer => {
    /* 处理 ArrayBuffer */
    // console.log(buffer);
});

// 从 blob 获取可读流(readableStream)
const readableStream = blob.stream();
const stream = readableStream.getReader();

(async()=>{
    while (true) {
        // 对于每次迭代:value 是下一个 blob 数据片段
        let { done, value } = await stream.read();
        if (done) {
            // 读取完毕,stream 里已经没有数据了
            console.log('all blob processed.');
            break;
        }

        // 对刚从 blob 中读取的数据片段做一些处理
        console.log(value);
    }
})()
<!--index.html-->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>blob</title>
</head>
<body>
    <img src="data:image/png;base64,R0lGODlhDAAMAKIFAF5LAP/zxAAAANyuAP/gaP///wAAAAAAACH5BAEAAAUALAAAAAAMAAwAAAMlWLPcGjDKFYi9lxKBOaGcF35DhWHamZUW0K4mAbiwWtuf0uxFAgA7">
    <a download="hello.txt" href='#' id="link">Download</a>
    <script src="blob.js"></script>
</body>
</html>

  • 7
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值