base64转图片的代码

base64转图片,之后如何保存为一个文件?用js代码或者在线工具即可搞定
js代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
function dataURLtoBlob(dataurl) {
var arr = dataurl.split(',');
var mime = arr[0].match(/:(.*?);/)[1];
var bstr = atob(arr[1]);// base64解码
var n = bstr.length;
var u8arr = new Uint8Array(n); // 开辟一个无符合n*8个字节的空间,最小操作单位为8位比特bit
while (n--) {
// base64解码之后,需要将每一位放置uint8array对象中
u8arr[n] = bstr.charCodeAt(n);
}
return new Blob([u8arr], { type: mime }); // 转换为浏览器内置的对象
}

function downloadFile(url, name='defaultFileName') {
var a = document.createElement("a")
a.setAttribute("href",url)
a.setAttribute("download",name)
a.setAttribute("target","_blank")
// 触发下载
let clickEvent = document.createEvent("MouseEvents");
clickEvent.initEvent("click", true, true);
a.dispatchEvent(clickEvent);
}

function downloadFileByBase64(base64,name) {
// 把base64转换成浏览器认识的blob对象
var myBlob = dataURLtoBlob(base64)
// 变成blobURL对象(html标签可以直接引用的对象)
var myUrl = URL.createObjectURL(myBlob)
downloadFile(myUrl, name)
}

// base64放在这里即可下载
downloadFileByBase64('data:image/png;base64,', 'customFileName')

原理

在了解了js内置的各种对象之后就能意会其中的原理了

fileReader

可以读取多种文件类型,读取结果也可以转换为多种类型的数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
fileInput = document.querySelector('input[type=file]');
fileInput.addEventListener('change', function() {
var fr = new FileReader();
// 监听读取结果
fr.onload = function() {
console.log("读取的结果为", this.result)
console.log("读取的类型为", typeof(this.result))
};
// 读取结果为arrayBuffer类型(只能读取一次)
fr.readAsArrayBuffer(this.files[0])
// 读取结果为text(只能读取一次)
fr.readAsText(this.files[0])
// 读取结果为其他类型(具体详见api)(只能读取一次)
fr.readAs...(this.files[0])
});

ArrayBuffer

ArrayBuffer类型的数据只能读取,不能修改,没有提供任何读写内存的方法,开辟连续的内存区域后,通过数据视图(如下类型)来操作

1
2
3
4
5
//创建一个长度为8的ArrayBuffer,此时开辟一个固定8个字节的缓冲区也就是64位
var buffer = new ArrayBuffer(8);

//返回大小
console.log(buffer.byteLength) //8

数据视图和类型数组

主要就是插入与读取arrayBuffer中的数据

类型数组TypedArray

  • Int8Array:8位有符号整数,长度1个字节。(-128~127)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    var a = new Int8Array(2);
    a[0] = -128;
    a[1] = 128;
    console.log(a[1] == a[0]); // true

    var b = new Int8Array(new ArrayBuffer(2));
    b[0] = -128;
    b[1] = 128;
    console.log(a.toString() == b.toString());// true
  • Uint8Array:8位无符号整数,长度1个字节。(0~255)
    new Uint8Array(1) 同等于 new Uint8Array(new ArrayBuffer(1))
  • Int16Array:16位有符号整数,长度2个字节。(-32768,32767)
  • Uint16Array:16位无符号整数,长度2个字节。(0~65535)
  • Int32Array:32位有符号整数,长度4个字节。(-2147483648~2147483647)
  • Uint32Array:32位无符号整数,长度4个字节。(0~4294967295)
  • Float32Array:32位浮点数,长度4个字节。
  • Float64Array:64位浮点数,长度8个字节。

以上几种统称为类型数组,看得出来的确有很多种类型,每种用法都大同小异
例子如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 创建8个字节长度的缓存冲
const buffer = new ArrayBuffer(8);

const uint8Array = new Uint8Array(buffer);

// log: [0, 0, 0, 0,0, 0, 0, 0]
console.log(uint8Array);

// 将buffer转化为Uint16Array
// Uint8Array中每一个元素表示两个字节(16位)
const uint16Array = new Uint16Array(buffer);

// log: Uint16Array(4) [ 0, 0, 0, 0 ]
console.log(uint16Array);

// 64位 8字节 -> 4个元素(log:4)
console.log(uint16Array.length);

数据视图DataView

DataView是一种底层的,更灵活的读取 ArrayBuffer 的视图,虽然有以上类型数组的'翻译器'操作ArrayBuffer,但是我们不想固化使用的情况下,就得用DataView对象来操作ArrayBuffer了

1
new DataView(buffer [, byteOffset [, byteLength]]);

第一个参数 buffer 为必填,它支持传入一个 ArrayBuffer 表示 DataView 中的源数据。
第二个参数 byteOffset 选填,它表示创建 DataView 时开头从 buffer 的哪个字节开始,可以作为启始偏移量。未指定时,默认从第一个字节开始。
第三个参数 byteLength 选填,它表示创建该 DataView 时的长度,当不传递默认时表示匹配 buffer 的长度。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// 创建8个字节长度的缓存冲
const buffer = new ArrayBuffer(8);

// 根据传入的buffer 从第一个字节开始,并且字节长度为匹配buffer的长度
const dataView = new DataView(buffer);

// 将DataView中偏移量为0个字节的字节,也就是第一个字节设置为十进制的1
dataView.setUint8(0, 1);
// 将DataView中偏移量为1个字节的字节,也就是第二个字节设置为十进制的2
dataView.setUint8(1, 2);

// 从dataView中偏移第0个字节,也就是第一个字节,获取8位
// log: 1
dataView.getUint8(0);

// 从dataView中偏移第一个字节获取八位,也就是获取第二个字节的值
// log: 2
dataView.getUint8(1);

// 偏移量为0个字节,获取后续16位大小(也就是获取前两个字节大小)
// log: 258
dataView.getUint16(0);

// 偏移量为2个字节,设置后16位大小为256(也就是设置第三个字节和第四个字节大小和为256)
dataView.setUint16(2, 256);

// 偏移量为2个字节,获取后16位大小
// log: 256
dataView.getUint16(2);

blob

const blob = new Blob( array, options );
第一个参数 array 是一个由ArrayBuffer, ArrayBufferView, Blob, DOMString 等对象构成的 Array
是浏览器环境上提供的一种大对象,通常是影像、声音或多媒体文件等原始数据的二进制对象,主要用作给后端传递数据,或者转换成BlobURL

BlobURL

blob对象是用作和后端打交道的,那如果和前端html文档打交道就得用BlogURL伪协议对象了。像img或者video或者background的src属性都用BlobURL,不能直接用Blob,可以理解为对blob对应的一个指针

DataURL

允许将较小的内容文件嵌入到html文档中。可以将其用作BlobURL的替代
其格式为:

1
2
3
4
5
data:[<mediatype>][;base64],data
data:前缀
mediatype表明数据类型,是一个MIME类型字符串,如image/jpeg表示一个JPEG图片文件。如果省略,默认值为text/plain;charset=US-ASCII。
base64:标志位(如果是文本,则可选)
data:数据本身

Array

js数组类型同[],其功能强大能在各种环境下使用,但不一定最优适用于环境