# JS 数据对象
# Blob
Blob (opens new window)(Binary Large Object)表示二进制类型的大对象。在数据库管理系统中,将二进制数据存储为一个单一个体的集合。Blob 通常是影像、声音或多媒体文件。在 JavaScript 中 Blob 类型的对象表示不可变的类似文件对象的原始数据。
- FileReader可以操作Blob对象
- var fileReader = new FileReader();
- fileReader.readAsText(blob):返回文本,需要指定文本编码,默认为 UTF-8。
- fileReader.readAsArrayBuffer(blob):返回 ArrayBuffer 对象。
- fileReader.readAsDataURL(blob):返回 Data URL。
- fileReader.readAsBinaryString(blob):返回原始的二进制字符串。
URL.createObjectURL 将 Blob 转换为 base64 编码的字符串。
# Base64
Base64 是一种基于 64 个可打印字符来表示二进制数据的表示方法,普遍应用于需要通过被设计为处理文本数据的媒介上储存和传输二进制数据而需要编码该二进制数据的场景。
在 JavaScript 中,有两个函数被分别用来处理解码和编码 base64 字符串:
# BlobURL
BlobURL (opens new window)(ObjectURL)是一种伪协议,只能由浏览器在内部生成,我们知道script/img/video/iframe等标签的src属性和background的url可以通过url和base64来显示,我们同样可以把blob或者file转换为url生成BlobURL来展示图像,BlobURL允许Blob和File对象用作图像,下载二进制数据链接等的URL源。
- BlobURL并不代表数据本身,数据存储在浏览器中,BlobUrl只是访问它的key。数据会一直有效,直到关闭浏览器或者手动清除。 因此即使将 BlobUrl传递给服务器等也无法访问数据。
- URL.revokeObjectURL(src); // 可以手动清除数据
# DataUrl
DataUrl (opens new window) 允许内容的创建者将较小的文件嵌入到文档中。由于可以将其用作URL的替代,因此DataURL和BlobUrl一样可以在script/img/video/iframe等标签的src属性和background的url中使用,用法与BlobUrl基本一致。
data:[<mediatype>][;base64],data
data:前缀
mediatype表明数据类型,是一个MIME类型字符串,如image/jpeg表示一个JPEG图片文件。如果省略,默认值为text/plain;charset=US-ASCII。
base64:标志位(如果是文本,则可选)
data:数据本身
2
3
4
5
DataUrl是直接编码的数据本身。关闭浏览器后仍然可以在地址栏访问,DataUrl由于数据本身由URL表示,因此可以将其保存在Cookie中传递给服务器。 BlobUrl的长度一般比较短,但DataUrl因为直接存储图片base64编码后的数据,往往很长(Base64编码的数据体积通常会比二进制格式的图片体积大1/3。),因此当显式大图片时,使用BlobUrl能获取更好的可能性,速度和内存比DataUrl更有效。 DataUrl不会被浏览器缓存,但是小部分会通过css缓存,如避免了让图片独自产生一次HTTP请求,不会每次使用时都加载一次。 BlobUrl始终是唯一字符串,即时你每次传递相同的Blob,每次也会生成不同的BlobUrl;DataUrl值跟随blob变化。
# ArrayBuffer
ArrayBuffer (opens new window) 对象用于表示通用的,固定长度的原始二进制数据缓冲区。不能直接操纵 ArrayBuffer 的内容,而是需要创建一个类型化数组对象或 DataView 对象,该对象以特定格式表示缓冲区,并使用该对象读取和写入缓冲区的内容。
function GET(url, callback) {
let xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.responseType = 'arraybuffer'; // or xhr.responseType = "blob";
xhr.send();
xhr.onload = function(e) {
if (xhr.status != 200) {
alert("Unexpected status code " + xhr.status + " for " + url);
return false;
}
callback(new Uint8Array(xhr.response)); // or new Blob([xhr.response]);
};
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# Blob与ArrayBuffer的区别:
- Blob 对象是不可变的,而 ArrayBuffer 是可以通过 TypedArrays 或 DataView 来操作。
- ArrayBuffer 是存在内存中的,可以直接操作。而 Blob 可以位于磁盘、高速缓存内存和其他不可用的位置。
- Blob 与 ArrayBuffer 对象之间是可以相互转化的:
- 使用 FileReader 的 readAsArrayBuffer() 方法,可以把 Blob 对象转换为 ArrayBuffer 对象;
- 使用 Blob 构造函数,如 new Blob([new Uint8Array(data]),可以把 ArrayBuffer 对象转换为 Blob 对象。
# TextEncoder
接受一个 USVString (opens new window) 作为输入,返回一个包含文本的 Uint8Array (opens new window),其中的文本使用 UTF-8 编码。
# TextDecoder
TextDecoder (opens new window)接口表示一个文本解码器,一个解码器只支持一种特定文本编码,例如 utf-8、iso-8859-2、koi8、cp1261,gbk 等等。解码器将字节流作为输入,并提供代码点流作为输出。
# createImageBitmap
方法存在 windows 和 workers 中. 它接受各种不同的图像来源, 并返回一个Promise (opens new window), resolve为ImageBitmap (opens new window). 可选地参数,图像被剪裁成自(sx,sy)且宽度为sw,高度为sh的像素的矩形。
createImageBitmap(image[, options]).then(function(response) { ... }); createImageBitmap(image, sx, sy, sw, sh[, options]).then(function(response) { ... });
image 一个图像源, 可以是一个 img (opens new window), SVG image (opens new window), video (opens new window), canvas (opens new window), HTMLImageElement (opens new window), SVGImageElement (opens new window), HTMLVideoElement (opens new window), HTMLCanvasElement (opens new window), Blob (opens new window), ImageData (opens new window), ImageBitmap (opens new window), 或 OffscreenCanvas (opens new window) 对象.
# 场景示例
从服务器端获取byteArray,解码获取base64字符串,base64字符串解析成blob二进制流数据,创建ImageBitmap对象,应用到纹理对象。
const xhr = new XMLHttpRequest()
xhr.open('GET', url)
xhr.responseType = 'arraybuffer' //设置返回格式
xhr.onload = () => {
var data = xhr.response;
textImgArrayBuffer =new Uint8Array(data);
}
xhr.send()
let utf8decoder = new TextDecoder(); // default 'utf-8' or 'utf8'
let textImgStr = utf8decoder(textImgArrayBuffer);
fetch(textImgStr).then(function (response) {
response.blob().then(function (blob) {
createImageBitmap(blob, {
'imageOrientation': 'flipY'
}).then(function (bitmap) {
console.log(bitmap);
// gl.texImage2D(target, level, internalformat, format, type, ImageBitmap? pixels);
}, onError);
}, onError);
}, onError);
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23