最近有涉及到图片格式转换及压缩的需求,在这里统一归纳一下
File 转为 base64 格式
/**
** File 转为 base64 格式
** @param file: File 格式的文件,比如从 input 框中选择的文件
*/
public fileToBase64(file: File) {
const fileReader = new FileReader();
fileReader.readAsDataURL(file);
return new Promise(resolve => {
fileReader.onload = () => {
resolve(fileReader.result);
};
});
}
base64 转为 File 格式
/**
** base64 转为 File 格式
** @param baseString: base64 字符流
*/
public async base64ToFile(baseString: string): Promise<File> {
const res: Response = await fetch(dataUrl);
const blob: Blob = await res.blob();
const imageType = this.getImageType(baseString);
const result = new File([blob], '图片', { type: imageType });
return result;
}
/**
** 从 base64 字符流中获取图片格式
** @param baseString: base64 字符流
*/
private getImageType(baseString: string): string{
const imgType = baseString.substring("data:image/".length, baseString.indexOf(";base64"));
return imgType;
}
保存非同源 url 图片至本地
/**
** 将图片 url 转换为 blob 格式
** @param httpUrl: 非同源图片链接,如 https://cdn.aaa.com/bbb.jpg
*/
private async urlToBlob(httpUrl) {
const res: Response = await fetch(httpUrl);
const blob: Blob = await res.blob();
const blobUrl = URL.createObjectURL(blob);
return blobUrl;
}
/**
** 下载图片到本地
** @param blobUrl: blob 格式的图片文件
** @param name: 图片名称
*/
private 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, maxH = 800, 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) {
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');
let imgData = ''; // 存储压缩后的图片
canvas.width = targetWidth; // 设置绘图的宽度
canvas.height = targetHeight; // 设置绘图的高度
// 使用drawImage重新设置img标签中的图片大小,实现压缩和图片裁剪
context.drawImage(image, 0, 0, targetWidth, targetHeight);
// 使用toDataURL将canvas上的图片转换为base64格式, 有损压缩为原来的0.6,最小为0.1
imgData = canvas.toDataURL(file.type, quality);
resolve(imgData);
};
});
}
网友评论