Web开发过程中,有时候我们需要将一些用二进制流表示的图片,转化为Base64格式,让图片可以在img标签中显示,下面将展示如何使用js编码将图片转换为Base64格式。

1. Binary To Base64

其实只需要一行代码就可以实现

// arrayBuffer为接收到的二进制数据
let imgBase64 = 'data:image/png;base64,' + window.btoa(String.fromCharCode(...new Uint8Array(arrayBuffer)));

但是,如果图片比较大(图片大于一百多k的时候),使用这种方法进行转换时,会抛出错误Uncaught RangeError: Maximum call stack size exceeded,这是因为String.fromCharCode方法无法一次处理这么大的数据,可以替换为下面的代码

// blob为接收到的二进制数据
let imgBase64 = window.btoa(new Uint8Array(arrayBuffer).reduce(function (data, byte) {
    return data + String.fromCharCode(byte);
}, ''));

使用reduce来依次进行拼接

2. Data URLs

在上面中解决方法中,类似data:image/png;base64,这样的前缀,作为开发人员,我们经常会看到,但是我们可能从来都没有考虑过它的含义。

实际上,

Data URLs,即前缀为 data: 协议的URL,其允许内容创建者向文档中嵌入小文件。

这里的data:httphttps:等类似,格式如下

data:[<mediatype>][;base64],<data>

其中mediatype;base64都是可选的,这里不要忘记,,否则无法解析。

常见的示例如下所示

data:,文本数据
data:text/plain,文本数据
data:text/css,CSS代码
data:text/css;base64,base64编码的CSS代码
data:text/javascript,Javascript代码
data:text/javascript;base64,base64编码的Javascript代码
data:image/gif;base64,base64编码的gif图片数据
data:image/png;base64,base64编码的png图片数据
data:image/jpeg;base64,base64编码的jpeg图片数据
data:image/x-icon;base64,base64编码的icon图片数据

上面的示例,在编码正确的情况下,都可以输入浏览器地址栏获取结果,注意中文会出现乱码

3. btoa & atob

IE10+的浏览器开始,所有浏览器都原生提供了base64的解码和编码方法,即window.atob()window.btoa()

Base64库的功能类似,但是原生的base64解码和编码方法在旧版本的浏览器中存在兼容性问题,所以为了解决兼容性问题,在旧版本的浏览器中,依旧需要使用Base64库,或者自己实现。

4. ArrayBuffer

首先看一个使用场景

//sourceUrl 可以是本地服务器文件,也可以是远程服务器文件
//eg 
//服务器根目录有mm.jpg文件,那么sourceUrl=mm.jpg,实际请求时请求的路径为http://localhost:port/mm.jpg
//fetch
const response = await fetch(sourceUrl, {method: 'GET'})
const responseData = await response.arrayBuffer()
let imgBase64 = window.btoa(new Uint8Array(responseData).reduce(function (data, byte) {
    return data + String.fromCharCode(byte);
}, ''));

ArrayBuffer是无法直接被使用的,需要通过TypedArrayDataView对象进行操作,它们会将缓冲区中的数据表示为特定的格式,进而通过这些特定的格式来读写缓冲区的内容。

这里之所以要用Uint8Array作为TypedArray而不是Uint16等,是因为window.btoa创建的是ASCII字符串,而ASCII的范围就是0~255,所以用Uint8

5. 转换过程

  1. 获取ArrayBuffer对象
  2. 转换为Uint8Array对象
  3. 转换为普通字符串
  4. 转换为base64编码的字符串
  5. 拼接为Data URL格式

参考资料