一文搞懂Blob, Base64, File, FileReader

目录
文章目录隐藏
  1. Blob
  2. Base64
  3. File
  4. FileReader

通过本文让大家再遇到流类型文件处理时候不在发怵,第一时间可以通过我的文章搞定你的需求,一起看一下吧。

Blob

1. 其属于浏览器 File API 的一部分:

  • type: 值类型是 string,通常是MIME-type
  • blobParts: 一系列其他 Blob 对象,string,或是 BufferSource

一文搞懂 Blob, Base64, File, FileReader

/*
blobParts: Blob|string|BufferSource|由它们组成的数组
options: {
    type: MIME-type 类型,
    endings: 是否转换换行符; "transparent" | "native"
}
*/
new Blob(blobParts, options)
1et hello = new uint8Array([12,112,18,98,121]);
1et blob = new Blob([hello,' ', 'world'],{type: "text/plain"});

2. 方法

Blob 对象不可修改,类似字符串,但可以通过 slice 创建一个新的。

// contentType: 返回的 blob 的 type;默认跟原 blob 一样, 非必填
blob.slice([byteStart], [byteEnd], [contentType?])

3. blob 作为 URL

/* url 形式:blob:<origin>/<uuid> */
/* 大概长这样:b1ob:https://javascript,info/2el887d3-32fe-34d3-eds3-9eid78sd78d8de */
url = URL.createobjectURL(blob);

使用上面URL.createobjectURL生产的是一个占用了内存的映射,因此内存不会自动回收,需要调用URL.revokeObjectURL方法销毁内存。否则长期搁置会导致内存泄漏,具体就是浏览器卡死。

let blob =new Blob(["He11o, world!"],{type: "text/plain"});
let link = document.createElement('a');
link.download = 'hello.txt';
link.href = URL.createobjectURL(blob);
link.click();
URL.revokeobjectuRL(link.href);

4. blob 作为 base64 用于 dataUrl

使用浏览器内置的 fileReader 方法可以将 blob 转换成 base64,用于 data-url。

data-url 可以和普通 url 一样使用:

let reader = new FileReader();
reader.readAsDataURL(blob);
reader.onload = function(){
  /*将 b1ob 编码成 base64 需要时间*/
  /*data ur1 格式:data:[<mediatype>][;base64],<data>*/
  /*大概长这样:data:image/png;base64,xxxxxx...*/
  link.href = reader.resut; //data url
}
转换形式 内存 编码 格式
blob – url 手动释放 无需编码,无卡顿风险 blob: <origin>/ <uuid>
blob – data-url 无需释放 需要编码,有卡顿风险 data: <mediaType>;base64,<data>

5. blob 可以通过 canvas 实现图片处理

将图片绘制到 cavans 中,可以对图片进行滤镜,效果,旋转,裁切等操作

需要调用 canvas 的 toBlob 进行绘制。

通过 canvas 下载一张图片:

/* 这里表示将 html 页面上已经加载好的图片获取到,通过 canvas 下载这张图片*/
let img = document.queryselector('img');
const canvas = document.getElementById("canvas");
canvas.width = img.clientwidth;
canvas.height = img.clientHeight;
let context=canvas.getcontext('2d');
context.drawImage(img,0,0);
canvas.toBlob((blob) => {
  let link = document.createElement('a');
  link.href = URL.createobjectURL(blob);
  link.click();
  URL.revokeobjectuRL(link.href);
});

使用 canvas 读取一张图片并加载到页面上:

/* 这里表示从 canvas 内,读取一张图片并加载到页面上,这里的图片是被 canvas 处理过后的图片 */
const canvas = document.getElementById("canvas");
canvas.toBlob((blob) => {
  const newImg = document.createElement("img");
  const url = URL.createObjectURL(blob);
  newImg.onload = () => {
 // 不再需要读取该 blob,因此释放该对象
 URL.revokeObjectURL(url);
  };
  newImg.src = url;
  document.body.appendChild(newImg);
});

指定图片格式、控制图片质量:

/* 返回一个:JPEG 格式 95% 图像质量的图片 */
canvas.toBlob(
  (blob) => {
 /* … */
  },
  "image/jpeg", // 第二个参数用于控制图片格式
  0.95, // 控制图片质量为 95%
);

6. Blob 转换成 ArrayBuffer

转成 arraybuffer 方便底层处理;例如:音频频谱显示,视频效果滤镜等等

// blob 为 Blob 对象
const bufferPromise = await blob.arrayBuffer();
blob.arrayBuffer().then(buffer => /* process the ArrayBuffer */);
// 此处需要借助 fileReader 对象:
var blob = new Blob([1,2,3,4,5])
var reader = new FileReader()
reader.readAsArrayBuffer(blob)
reader.onload=function(result){
 console.log(result); // result 既是 arrayBuffer
}

7. Blob 转换成 stream

大多数用于上传/下载

const readableStream = blob.stream();
const stream = readableStream.getReader();
while(true){
 let { done, value } = await stream.read();
 if(done) { break; }
 // value 拿到的是碎片数据
 console.1og(value);
}

Base64

将二进制转换成 64 进制形式的算法换句话说:-将二进制数据(binary data)使用字符串(ASCll string)的形式表达出来。

无压缩(无数据损失),但是体积会变大。

用以下字符表示 64 进制下的 0-63,除此之外,=将作为分隔符。

ABCDEFGHIJKLMNOPORSTuvwxYZabcdefghijk1mnopqrstuvwxyz0123456789+/
/*一种变形:Base64 URL safe.为了避免 URL 解析中的问题而存在(+和/在浏览器 url 内会被转义导致信息出错)*/
ABCDEFGHIJKLMNOPORSTuVwxYZabcdefghijk1mnopqrstuvwxyz0123456789-
  • blob 转 base64
  • buffer 转 base64
    // 2n 为 2 的 n 次方; 一般 2^n 为 8,16,32 这样的数值。意思是创建一个 8,16,32 字节的缓冲区(若有需要可以在调用 DataView 字节序实现 32 位/64 位操作系统的补全方案,请自行在 mdn 搜索 DataView)
    var buffer = new ArrayBuffer([2^n]);
    // 先将 buffer 转 blob
    var blob = new Blob([buffer], [MIME-type?]) // MIME-type 选填
    // 然后调用 b1ob 转 base64 的方法
  • string 转 base64(有限制的方法)

    简单但有限制的方法: window.atob()
    待转换字符串的每个字符,其码点不能超过 127(0x7f); 128-255 转换出错但不报错,256-转换报错
    atob 中 a 代表:ascii 码,b 代表 binary
    其相似方法有:window.btoa(); 将 binary 转成 ascii

(无限制的方法) 点击这里

File

File 类继承至 Blob,扩展了一些文件系统相关的功能
除继承至 Blob 的方法和属性, 还新增 name,lastModified 属性

  • 获取 file 对象,通过 new File()构造器
    /* 
    fileParts:数组,值是 B1ob/Buffersource/string
    fileName:文件名字符串
    options:{
     lastModified:时间戳,上次修改的时间
    }
    */
    new File(fileParts,fileName, [options])
  • 获取 file 对象,通过<input type=”file”>
    <!-多选文件-->
    <input type="file" id="filepicker" multiple />
    <div>
      <p>选定文件列表:</p>
      <ul id="output"></ul>
    </div>
    <script>
    const output = document.getElementById("output");
    const filepicker = document.getElementById("filepicker");
    
    filepicker.addEventListener("change", (event) => {
      const files = event.target.files;
      output.textContent = "";
    
      for (const file of files) {
     const li = document.createElement("li");
     li.textContent = file.name;
     output.appendChild(li);
      }
    });
    </script>
    <!-单选文件-->
    <input type="file" onchange="changefile(this)" />
    <script>
    function changefile(input){
      let file = input.files[0];
      console.log(File name: ${file.name});
      console.log(File lastModified: ${file.lastModified});
    }
    </script>

 

FileReader

FileReader 唯一的功能就是读取 Blob 对象(也包含 File 啦)中的数据,一些高级操作(slice),不需要读取,直接调用 Blob 方法。读取文件需要事件,读取完成通过事件传递读取数据。

let reader =new FileReader()
// reader 方法.异步的,解析完调用回调
reader.readAsArrayBuffer(blob)
reader.readAsText(blob, [encoding])
reader.readAsDataURL(b1ob)
reader.abort()

// read 读取过程中的事件
reader.onloadstart
reader.onprogress
reader.onload
reader.onabort
reader.onerror
reader.onloadend

以上就是关于 Blob, Base64, File, FileReader 相关内容,希望对大家有用。

「点点赞赏,手留余香」

0

给作者打赏,鼓励TA抓紧创作!

微信微信 支付宝支付宝

还没有人赞赏,快来当第一个赞赏的人吧!

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。
码云笔记 » 一文搞懂Blob, Base64, File, FileReader

发表回复