/**
|
* Vue3 在线图片 URL 转 base64
|
* @param {string} imgUrl - 在线图片地址(如 "https://xxx.com/sign.png")
|
* @param {Object} options - 配置项
|
* @param {string} options.format - 图片格式(默认 png,可选 jpeg/webp)
|
* @param {number} options.quality - 压缩质量(0-1,默认 1.0 无损)
|
* @returns {Promise<string>} 完整 base64 字符串(含 data:image/xxx;base64, 前缀)
|
*/
|
export function imageUrlToBase64(
|
imgUrl,
|
{ format = 'png', quality = 1.0 } = {}
|
) {
|
return new Promise((resolve, reject) => {
|
if (!imgUrl) {
|
reject(new Error('图片 URL 不能为空'));
|
return;
|
}
|
|
// 处理 URL 特殊字符(如空格、中文)
|
const encodedUrl = encodeURI(imgUrl);
|
|
const img = new Image();
|
// 跨域关键配置(需图片服务器支持 CORS)
|
img.crossOrigin = 'Anonymous';
|
|
// 图片加载成功
|
img.onload = () => {
|
const canvas = document.createElement('canvas');
|
const ctx = canvas.getContext('2d');
|
if (!ctx) {
|
reject(new Error('Canvas 初始化失败'));
|
return;
|
}
|
|
// 保持图片原始尺寸(避免拉伸)
|
canvas.width = img.naturalWidth;
|
canvas.height = img.naturalHeight;
|
|
// 绘制图片(清除透明背景,适配 jpeg 格式)
|
if (format === 'jpeg') {
|
ctx.fillStyle = '#ffffff';
|
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
}
|
ctx.drawImage(img, 0, 0);
|
|
// 转换为 base64
|
try {
|
const base64 = canvas.toDataURL(`image/${format}`, quality);
|
resolve(base64);
|
} catch (err) {
|
reject(new Error(`base64 转换失败:${err.message}`));
|
}
|
|
// 释放内存(销毁临时元素)
|
canvas.remove();
|
img.remove();
|
};
|
|
// 图片加载失败(跨域、URL 无效、网络错误)
|
img.onerror = (err) => {
|
reject(new Error(`图片加载失败:${err.message},可能是跨域限制或 URL 无效`));
|
};
|
|
// 触发加载(必须放在回调绑定后)
|
img.src = encodedUrl;
|
});
|
}
|