项目中有用到上传图片、压缩图片、图片格式转化等功能,现将封装的方法整理如下:
input file 转为 base64 格式
/**
* File 转为 base64
*/
public fileToBase64(file: File) {
const fileReader = new FileReader();
fileReader.readAsDataURL(file);
return new Promise(resolve => {
fileReader.onload = () => {
resolve(fileReader.result);
};
});
}
base64 格式转为 File 格式
/**
* base64 转为 File 格式
*/
public async base64ToFile(dataUrl: string, file: File): Promise<File> {
const res: Response = await fetch(dataUrl);
const blob: Blob = await res.blob();
const result = new File([blob], file.name, { type: file.type });
return result;
}
将存于 url 链接中的文件转为 Blob 格式
/**
* 将url格式的文件转换为blob格式
* @param httpUrl: 后台给的文件地址
*/
public async urlToBlob(httpUrl) {
const res: Response = await fetch(httpUrl);
const blob: Blob = await res.blob();
const blobUrl = URL.createObjectURL(blob);
return blobUrl;
}
将 url 文件下载保存至本地
/**
* 保存文件到本地
*/
public downloadToLocal(blobUrl, name) {
// 创建虚拟a标签
const eleLink = document.createElement('a');
eleLink.download = name;
eleLink.style.display = 'none';
eleLink.href = blobUrl;
// 触发点击
document.body.appendChild(eleLink);
eleLink.click();
// 然后移除
document.body.removeChild(eleLink);
URL.revokeObjectURL(blobUrl);
}
压缩图片
/**
* 压缩图片
*/
public async compressedImg(file: File, maxW = 1080, quality = 0.6): Promise<string> {
// 将file文件转为base格式
const result: any = await this.fileToBase64(file);
// 新建一个img标签(不嵌入DOM节点,仅做canvas操作)
const image = new Image();
// 让该标签加载base64格式的原图
image.src = result;
// 图片加载完毕后再通过canvas压缩图片,图片还没加载完就压缩,结果图片是全黑的
return new Promise(resolve => {
image.onload = () => {
// 最大尺寸限制
const maxWidth = maxW;
// maxHeight = maxH;
// 图片原始尺寸
const originWidth = image.width,
originHeight = image.height;
// 目标尺寸
let targetWidth = originWidth,
targetHeight = originHeight;
// 图片尺寸超过限制时
if (originWidth > maxWidth) {
// 更宽,按照宽度限定尺寸
targetWidth = maxWidth;
targetHeight = Math.round(maxWidth * (originHeight / originWidth));
// if (originWidth / originHeight > maxWidth / maxHeight) {
// // 更宽,按照宽度限定尺寸
// targetWidth = maxWidth;
// targetHeight = Math.round(maxWidth * (originHeight / originWidth));
// } else {
// targetHeight = maxHeight;
// targetWidth = Math.round(maxHeight * (originWidth / originHeight));
// }
} else {
targetWidth = originWidth;
targetHeight = originHeight;
}
// 创建一个canvas元素
const canvas = document.createElement('canvas');
// context相当于画笔,里面有各种可以进行绘图的API
const context = canvas.getContext('2d');
// 压缩后图片的宽度,例如 imageWidth = image.width / 2;
let imgData = ''; // 存储压缩后的图片
canvas.width = targetWidth; // 设置绘图的宽度
canvas.height = targetHeight; // 设置绘图的高度
// 使用drawImage重新设置img标签中的图片大小,实现压缩和图片裁剪
context.drawImage(image, 0, 0, targetWidth, targetHeight);
// 使用toDataURL将canvas上的图片转换为base64格式, 有损压缩为原来的0.6,默认值为0.92,最小为0.1
imgData = canvas.toDataURL(file.type, quality);
resolve(imgData);
};
});
}