本文目的是让同学们以后遇到流类型文件处理时候不在发怵,第一时间可以通过我的文章搞定你的需求
Blob
其属于浏览器File API的一部分:
- type: 值类型是string,通常是MIME-type
- blobParts: 一系列其他Blob对象,string,或是BufferSource
/*
blobParts: Blob|string|BufferSource|由它们组成的数组
options: {
type: MIME-type类型,
endings: 是否转换换行符; "transparent" | "native"
}
*/
new Blob(blobParts, options)
let hello = new uint8Array([12,112,18,98,121]);
let blob = new Blob([hello,' ', 'world'],{type: "text/plain"});
方法
Blob对象不可修改,类似字符串,但可以通过slice创建一个新的// contentType: 返回的blob的type;默认跟原blob一样, 非必填 blob.slice([byteStart], [byteEnd], [contentType?])
blob作为URL
/* url形式:blob:<origin>/<uuid> */ /* 大概长这样blob: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);
blob作为base64用于dataUrl
使用浏览器内置的fileReader方法可以将blob转换成base64;用于data-url
data-url可以和普通url一样使用let reader = new FileReader(); reader.readAsDataURL(blob); reader.onload = function(){ /*将blob编码成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> |
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% );
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 }
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选填 // 然后调用blob转base64的方法
- string转base64
(有限制的方法)
简单但有限制的方法: window.atob() 待转换字符串的每个字符,其码点不能超过127(0x7f); 128-255转换出错但不报错,256-转换报错 atob中a代表:ascii码,b代表binary 其相似方法有:window.btoa(); 将binary转成ascii
(无限制的方法)
https://developer.mozilla.org/zh-CN/docs/Glossary/Base64File
File类继承至Blob,扩展了一些文件系统相关的功能
除继承至Blob的方法和属性, 还新增name,lastModified属性- 获取file对象,通过new File()构造器
/* fileParts:数组,值是Blob/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(blob) reader.abort() // read读取过程中的事件 reader.onloadstart reader.onprogress reader.onload reader.onabort reader.onerror reader.onloadend
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。