图片压缩

This commit is contained in:
lyc 2024-07-19 17:19:46 +08:00
parent 23cd12c46b
commit 222e25a369
1 changed files with 96 additions and 5 deletions

View File

@ -50,13 +50,14 @@ export default class Export {
}
// 导出为图片
exportImage({
async exportImage({
type = 'image/png',
renderBg = true,
useBlob = false,
paddingX = 10,
paddingY = 10,
onlySelected
onlySelected,
backgroundColor
} = {}) {
// 计算所有元素的外包围框
let { minx, maxx, miny, maxy } = getMultiElementRectInfo(
@ -64,6 +65,11 @@ export default class Export {
)
let width = maxx - minx + paddingX * 2
let height = maxy - miny + paddingY * 2
if(!width && !height){
width = this.app.width
height = this.app.height
backgroundColor = '#ffffff'
}
// 创建导出canvas
let { canvas, ctx } = createCanvas(width, height, {
noStyle: true,
@ -73,12 +79,12 @@ export default class Export {
this.saveAppState()
this.changeAppState(minx - paddingX, miny - paddingY, ctx)
// 绘制背景颜色
if (renderBg && this.app.state.backgroundColor) {
if (renderBg && backgroundColor ? backgroundColor : this.app.state.backgroundColor) {
this.app.background.canvasAddBackgroundColor(
ctx,
width,
height,
this.app.state.backgroundColor
backgroundColor
)
}
// 绘制元素到导出canvas
@ -96,9 +102,94 @@ export default class Export {
}, type)
})
} else {
return canvas.toDataURL(type, 0.9)
return await this.compressImg(canvas.toDataURL(type), 1, 0.2,type)
}
}
/**
* 压缩base64图片的函数
*
* @param {string} base64 - 图片的base64编码
* @param {number} multiple - 缩放比例
* @param {number} quality - 输出图片的质量0.0到1.0之间
* @param {string} format - 输出图片的格式默认为"image/webp" 可选参数 image/pngimage/jpegimage/webp
* @param {number} min - 压缩后图片的最小KB大小
* @param {number} max - 压缩后图片的最大KB大小
* @returns {Promise<string>} - 返回压缩后的图片的base64编码
*/
compressImg(base64, multiple, quality, format = "image/webp", min, max) {
return new Promise((resolve, reject) => {
try {
// 如果base64为空则直接返回
if (!base64) {
return;
}
// 创建一个新的Image对象
let newImage = new Image();
// 设置Image对象的src为传入的base64编码
newImage.src = base64;
// 设置crossOrigin属性为'Anonymous',用于处理跨域图片
newImage.setAttribute('crossOrigin', 'Anonymous');
// 定义图片的宽度、高度和缩放比例
let imgWidth, imgHeight, proportion;
// 当图片加载完成后执行的操作
newImage.onload = function() {
// 计算缩放后的宽度
proportion = this.width * multiple;
// 记录原始宽度和高度
imgWidth = this.width;
imgHeight = this.height;
// 创建一个canvas元素
let canvas = document.createElement('canvas');
// 获取canvas的2D渲染上下文
let ctx = canvas.getContext('2d');
// 设置canvas的宽高按照等比例缩放
// 等比例缩小放大
canvas.width = proportion;
canvas.height = proportion * (imgHeight / imgWidth);
// 清除canvas上的内容
ctx.clearRect(0, 0, canvas.width, canvas.height);
// 在canvas上绘制缩放后的图片
ctx.drawImage(this, 0, 0, canvas.width, canvas.height);
// 将canvas转换为base64编码的图片
let smallBase64 = canvas.toDataURL(format, quality);
// 如果设置了最小KB大小并且压缩后的图片大小小于最小KB大小则增加质量并重新压缩
if (min && smallBase64.length / 1024 < min) {
while (smallBase64.length / 1024 < min) {
quality += 0.01;
smallBase64 = canvas.toDataURL(format, quality);
}
}
// 如果设置了最大KB大小并且压缩后的图片大小大于最大KB大小则减小质量并重新压缩
else if (max && smallBase64.length / 1024 > max) {
while (smallBase64.length / 1024 > max) {
quality -= 0.01;
smallBase64 = canvas.toDataURL(format, quality);
}
}
// 将压缩后的图片的base64编码作为Promise的解决值返回
resolve(smallBase64);
};
} catch (error) {
reject(error)
throw new Error(error);
}
});
}
// 保存app类当前状态数据
saveAppState() {