谈谈前端二进制

整个文章围绕前端如何进行图片处理,然后穿插介绍二进制、Blob、Blob URL、Base64、Data URL、ArrayBuffer、TypedArray、DataView 和图片压缩相关的知识点。

一、 「选择本地图片 -> 图片预览」

1.1 FileReader API

在支持 FileReader API 的浏览器中,我们也可以利用该 API 方便实现图片本地预览功能。


image.png


  
    
    
    图片本地预览示例
  
  
    

阿宝哥:图片本地预览示例

FileReader的一些API:
https://developer.mozilla.org/zh-CN/docs/Web/API/FileReader

我们可以在 Elements 面板中看到 Data URL 的 数据:


image.png

这串奇怪的字符串被称为 Data URL,它由四个部分组成:前缀(data:)、指示数据类型的 MIME 类型、如果非文本则为可选的 base64 标记、数据本身:

data:[][;base64],

mediatype 是个 MIME 类型的字符串参考:https://www.w3school.com.cn/media/media_mimeref.asp

在 Web 项目开发过程中,为了减少 HTTP 请求的数量,对应一些较小的图标,我们通常会考虑使用 Data URL 的形式内嵌到 HTML 或 CSS 文件中。「但需要注意的是:如果图片较大,图片的色彩层次比较丰富,则不适合使用这种方式,因为该图片经过 base64 编码后的字符串非常大,会明显增大 HTML 页面的大小,从而影响加载速度。」

1.2 Base64

「Base64」 是一种基于 64 个可打印字符来表示二进制数据的表示方法。2^6=64,6个位标识一个字符。3个字节3*8=24。标识4个base64的字符。

「Base64 常用于在处理文本数据的场合,表示、传输、存储一些二进制数据,包括 MIME 的电子邮件及 XML 的一些复杂数据。」

在 JavaScript 中,有两个函数被分别用来处理解码和编码 base64 字符串:

  1. btoa():该函数能够基于二进制数据 “字符串” 创建一个 base64 编码的 ASCII 字符串。
  2. atob():该函数能够解码通过 base64 编码的字符串数据。

需要注意的是 base64 只是一种数据编码方式,目的是为了保障数据的安全传输。但标准的 base64 编码无需额外的信息,即可以进行解码,是完全可逆的。因此在涉及传输私密数据时,并不能直接使用 base64 编码,而是要使用专门的对称或非对称加密算法。

二、网络下载图片 -> 图片预览

除了可以从本地获取图片之外,我们也可以使用 fetch API 从网络上获取图片,然后在进行图片预览。当然对于网络上可正常访问的图片地址,我们可以直接把地址赋给 img 元素,但是有的图片加密了,因为我们需要在 Web Worker 中使用 fetch API 获取图片数据并进行解密操作。


image.png


  
    
    
    获取远程图片预览示例
  
  
    

阿宝哥:获取远程图片预览示例

image.png

以上的特殊字符串,我们称之为 「Object URL」,相比前面介绍的 Data URL,它简洁很多。接下来我们来认识一下 Object URL 这种协议。

2.1 Object URL

Object URL 是一种伪协议,也被称为 Blob URL。它允许 Blob 或 File 对象用作图像,下载二进制数据链接等的 URL 源。 在浏览器中,我们使用 URL.createObjectURL 方法来创建 Blob URL,该方法接收一个 Blob 对象,并为其创建一个唯一的 URL,其形式为 blob:/,对应的示例如下:

blob:https://example.org/40a5fb5a-d56d-4a33-b4e2-0acf6a8e5f641

浏览器内部为每个通过 URL.createObjectURL 生成的 URL 存储了一个 「URL → Blob」 映射。因此,此类 URL 较短,但可以访问 Blob。生成的 URL 仅在当前文档打开的状态下才有效。但如果你访问的 Blob URL 不再存在,则会从浏览器中收到 404 错误。

上述的 Blob URL 看似很不错,但实际上它也有副作用。虽然存储了 URL → Blob 的映射,但 Blob 本身仍驻留在内存中,浏览器无法释放它。映射在文档卸载时自动清除,因此 Blob 对象随后被释放。但是,如果应用程序寿命很长,那不会很快发生。因此,如果我们创建一个 Blob URL,即使不再需要该 Blob,它也会存在内存中。

针对这个问题,我们可以调用 URL.revokeObjectURL(url) 方法,从内部映射中删除引用,从而允许删除 Blob(如果没有其他引用),并释放内存。

既然讲到了 Blob URL,不得不提 Blob。那么什么是 Blob 呢?我们继续往下看。

2.2 Blob API

Blob(Binary Large Object)表示二进制类型的大对象。在数据库管理系统中,将二进制数据存储为一个单一个体的集合。Blob 通常是影像、声音或多媒体文件。「在 JavaScript 中 Blob 类型的对象表示不可变的类似文件对象的原始数据。」

image.png

myBlob 对象含有两个属性:size 和 type。其中 size 属性用于表示数据的大小(以字节为单位),type 是 MIME 类型的字符串。Blob 表示的不一定是 JavaScript 原生格式的数据。比如 File 接口基于 Blob,继承了 blob 的功能并将其扩展使其支持用户系统上的文件。

Blob 由一个可选的字符串 type(通常是 MIME 类型)和 blobParts 组成:

image.png
2.2.1 Blob 构造函数

Blob 构造函数的语法为:

var aBlob = new Blob(blobParts, options);
  1. blobParts:它是一个由 ArrayBuffer,ArrayBufferView,Blob,DOMString 等对象构成的数组。DOMStrings 会被编码为 UTF-8。
  2. options:一个可选的对象,包含以下两个属性:
    2.1 type —— 默认值为 "",它代表了将会被放入到 blob 中的数组内容的 MIME 类型。
    2.2 endings —— 默认值为 "transparent",用于指定包含行结束符 \n 的字符串如 何被写入。它是以下两个值中的一个:"native",代表行结束符会被更改为适合宿主操作系统文件系统的换行符,或者 "transparent",代表会保持 blob 中保存的结束符不变。
let myBlobParts = ['

Hello Semlinker

']; // an array consisting of a single DOMString let myBlob = new Blob(myBlobParts, {type : 'text/html', endings: "transparent"}); // the blob console.log(myBlob.size + " bytes size"); // Output: 37 bytes size console.log(myBlob.type + " is the type"); // Output: text/html is the type let hello = new Uint8Array([72, 101, 108, 108, 111]); // 二进制格式的 "hello" let blob = new Blob([hello, ' ', 'semlinker'], {type: 'text/plain'});

介绍完 Blob 构造函数,接下来我们来分别介绍 Blob 类的属性和方法:

image.png
2.2.2 Blob 属性

前面我们已经知道 Blob 对象包含两个属性:

  1. size(只读):表示 Blob 对象中所包含数据的大小(以字节为单位)。
  2. type(只读):一个字符串,表明该 Blob 对象所包含数据的 MIME 类型。如果类型未知,则该值为空字符串。
2.2.3 Blob 方法
  1. slice([start[, end[, contentType]]]):返回一个新的 Blob 对象,包含了源 Blob 对象中指定范围内的数据。
  2. stream():返回一个能读取 blob 内容的 ReadableStream。
  3. text():返回一个 Promise 对象且包含 blob 所有内容的 UTF-8 格式的 USVString。
  4. arrayBuffer():返回一个 Promise 对象且包含 blob 所有内容的二进制格式的 ArrayBuffer。

「Blob 对象是不可改变的」。我们不能直接在一个 Blob 中更改数据,但是我们可以对一个 Blob 进行分割,从其中创建新的 Blob 对象,将它们混合到一个新的 Blob 中。这种行为类似于 JavaScript 字符串:我们无法更改字符串中的字符,但可以创建新的更正后的字符串。

对于 fetch API 的 Response 对象来说,该对象除了提供 blob() 方法之外,还提供了 json()、 text() 、formData() 和 arrayBuffer() 等方法,用于把响应转换为不同的数据格式。

对于前面的示例,我们把响应对象转换为 ArrayBuffer 对象,同样可以正常显示从网络下载的图像,具体的代码如下所示:

阿宝哥:获取远程图片预览示例

转载:https://mp.weixin.qq.com/s/DoipkAca00MuXon8wRYPgQ

你可能感兴趣的:(谈谈前端二进制)