Fie对象 Image对象 base64 canvas对象 相互转换

在前端操作过程中,上传文件,图片是不可避免的,但有时候用户在前端页面操作完再上传,我们并没有文件对象,一般我们拿到的是 canvas image 等,有时候还可能是 base64 编码,这时我们该怎么上传文件呢?

我们先来理清楚一个关系

1
2
3
url/base64  →  Image  → canvas → base64 → File
base64
→ File → base64

编码实现

1
2
3
4
5
6
7
8
9
10
11
12
function urlToImgAsync(url) {
const img = new Image();
img.src = url;
return new Promise((resolve, reject) => {
img.onload = function (e) {
resolve(img);
};
img.onerror = function (e) {
reject(e);
};
});
}
1
2
3
4
5
6
7
8
9
10
11
function imgToCanvas(img) {
if (img instanceof Image) {
const canvas = document.createElement('canvas');
const cxt = canvas.getContext('2d');
canvas.width = img.width;
canvas.height = img.height;
cxt.drawImage(img, 0, 0);
return canvas;
}
throw new TypeError(`${Object.prototype.toString.call(img)} not a image`);
}
1
2
3
4
5
6
function canvasToData(canvas) {
if (canvas instanceof HTMLCanvasElement) {
return canvas.toDataURL();
}
throw new TypeError(`${Object.prototype.toString.call(canvas)} not a canvas`);
}
1
2
3
4
5
6
7
8
9
10
11
12
function dataToFile(data, file = 'file') {
let arr = data.split(',');
let mime = arr[0].match(/:(.*?);/)[1];
let suffix = mime.split('/')[1];
let bstr = atob(arr[1]);
let n = bstr.length;
let u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
return new File([u8arr], `${file}.${suffix}`, { type: mime });
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function fileToUrlAsync(file) {
console.log(file);
if (file instanceof File) {
const reader = new FileReader();
reader.readAsDataURL(file);
return new Promise((resolve, reject) => {
reader.onloadend = function (e) {
console.log(e);
resolve(e.target.result);
};
reader.onerror = function (e) {
console.log(e);
reject(e);
};
});
}
throw new TypeError(`${Object.prototype.toString.call(file)} not a file`);
}

任意组合示例:

1
canvasToData(imgToCanvas(await urlToImgAsync(`https://xxx.com/img.png`)));
-------------本文结束感谢您的阅读-------------
坚持原创技术分享,您的支持将鼓励我继续创作!
0%