ArrayBuffer转base64详解
先贴代码:
const base64String = window.btoa(String.fromCharCode(...new Uint8Array(buffer)))
看起来⾮常的简洁,优美。那么我们今天就来捋⼀捋,这个看似简单的背后,蕴含了怎样的原理。
⾸先我们得来说说arrayBuffer这回事。
在JavaScript中,有⼀个很常⽤的引⽤数据类型Array,你可以在⾥⾯放字符串、数字、对象、布尔值等等等等。它存放在堆中,可以⾃由增减。
⽽ArrayBuffer我们叫它类型化数组,它的诞⽣就是为了解决⼀个问题:操作⼆进制数据。
只由0和1组成的⼆进制数据往往是⾮常巨⼤的,上千个字节可以说司空见惯,传统的Array这时候处理起⼆进制数据起来就显得⾮常低效,所以ArrayBuffer出现了,它作为⼀块专⽤的内存区域存放在栈中,取数据⾮常快。
我们现在通过new ArrayBuffer(10)初始化⼀个buffer实例,看看会得到什么。
let buffer = new ArrayBuffer(10);
console.log(buffer);
ArrayBuffer(10) {}
[[Int8Array]]: Int8Array(10) [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[[Int16Array]]: Int16Array(5) [0, 0, 0, 0, 0]
[[Uint8Array]]: Uint8Array(10) [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
byteLength: 10
__proto__: ArrayBuffer
可以看到在ArrayBuffer中,主要存放了⼏个“视图”,Int8Array表⽰8位有符号整数数组,Int16Array表⽰16位有符号整数数组,Uint8Array则表⽰8位⽆符号整数数组。
当然,如果⽐如说我们想取出Int8Array这个数组来,是不能直接通过buffer.Int8Array来取的。这是因为ArrayBuffer不能直接通过下标去读写,我们需要把它转成⼀个类型化数组(TypedArray)。
const myTypedArray = new Uint8Array(buffer)
转化完之后,我们我们不仅可以通过下标去对类型化数组进⾏索引,也可以获取其length,当然TypedArray仍与普通的Array存在细微的区别,那就是假设我们⽤超出边界的索引语法去获取数组元素时,
字符串转数组编码方式TypedArray并不会去原型链中进⾏查。
现在我们已经拿到了这个类型化数组,是时候把它转成普通字符串了。看看String.fromCharCode这个函数,它接受的参数为⼀堆代码单元序列,输出⼀个普通字符串。⽽我们刚刚得到的类型化数组,⾥
⾯存放的正是代码单元。
const str = String.fromCharCode(...myTypedArray)
这⾥我们⽤拓展运算符...把类型数组的代码单元解出来,⼀次性转完,得到⼀个普通的字符串。
最后,我们需要借助⼀个window对象的⽅法,也就是btoa⽅法,它的作⽤是:把⼀个普通字符串编码成base-64格式的字符串。
有时候后台把图⽚资源通过arrayBuffer传给前端,这时候为了能正常显⽰,我们还需要在转化的base64字符串前⾯拼接
上data:image/jpeg;base64,
所以我们整理⼀下,可以得出这样⼀个函数:
const arrayBufferToBase64Img = (buffer) => {
const str = String.fromCharCode(...new Uint8Array(buffer));
return `data:image/jpeg;base64,${window.btoa(str)}`;
}
总结
得到⼀个ArrayBuffer ---> 转成类型化数组以正常读取 --> 转成普通字符串 --> 转成base64字符串
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论