/**
* HTML转图片工具
* 支持将HTML元素转换为PNG、JPEG格式的图片
* 使用html2canvas库实现
*/
class HTMLToImage {
constructor(options = {}) {
this.options = {
scale: 2, // 缩放比例,提高图片清晰度
useCORS: true, // 启用跨域图片支持
allowTaint: false, // 不允许污染画布
backgroundColor: '#ffffff', // 背景颜色
width: null, // 自定义宽度
height: null, // 自定义高度
...options
};
// 检查是否已加载html2canvas
if (typeof html2canvas === 'undefined') {
console.warn('html2canvas未加载,将动态加载...');
this.loadHtml2Canvas();
}
}
/**
* 将HTML元素转换为图片
* @param {HTMLElement} element - 要转换的HTML元素
* @param {Object} options - 转换选项
* @returns {Promise} - 返回图片的DataURL
*/
async toImage(element, options = {}) {
try {
// 确保html2canvas已加载
if (typeof html2canvas === 'undefined') {
await this.loadHtml2Canvas();
}
const mergedOptions = { ...this.options, ...options };
const canvas = await html2canvas(element, mergedOptions);
return canvas.toDataURL('image/png');
} catch (error) {
console.error('HTML转图片失败:', error);
throw error;
}
}
/**
* 将HTML元素转换为JPEG图片
* @param {HTMLElement} element - 要转换的HTML元素
* @param {number} quality - JPEG质量 (0-1)
* @param {Object} options - 转换选项
* @returns {Promise} - 返回图片的DataURL
*/
async toJPEG(element, quality = 0.92, options = {}) {
try {
if (typeof html2canvas === 'undefined') {
await this.loadHtml2Canvas();
}
const mergedOptions = { ...this.options, ...options };
const canvas = await html2canvas(element, mergedOptions);
return canvas.toDataURL('image/jpeg', quality);
} catch (error) {
console.error('HTML转JPEG失败:', error);
throw error;
}
}
/**
* 下载图片
* @param {string} dataURL - 图片的DataURL
* @param {string} filename - 文件名
*/
downloadImage(dataURL, filename = 'image.png') {
const link = document.createElement('a');
link.download = filename;
link.href = dataURL;
link.click();
}
/**
* 将图片DataURL转换为Blob对象
* @param {string} dataURL - 图片的DataURL
* @returns {Promise}
*/
dataURLToBlob(dataURL) {
return new Promise((resolve) => {
const byteString = atob(dataURL.split(',')[1]);
const mimeString = dataURL.split(',')[0].split(':')[1].split(';')[0];
const ab = new ArrayBuffer(byteString.length);
const ia = new Uint8Array(ab);
for (let i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i);
}
resolve(new Blob([ab], { type: mimeString }));
});
}
/**
* 获取图片的尺寸信息
* @param {string} dataURL - 图片的DataURL
* @returns {Promise<{width: number, height: number}>}
*/
getImageDimensions(dataURL) {
return new Promise((resolve) => {
const img = new Image();
img.onload = () => {
resolve({
width: img.width,
height: img.height
});
};
img.src = dataURL;
});
}
/**
* 批量转换多个元素
* @param {HTMLElement[]} elements - 要转换的元素数组
* @param {Object} options - 转换选项
* @returns {Promise} - 返回图片DataURL数组
*/
async batchConvert(elements, options = {}) {
const results = [];
for (let i = 0; i < elements.length; i++) {
try {
const dataURL = await this.toImage(elements[i], options);
results.push(dataURL);
console.log(`第 ${i + 1} 个元素转换完成`);
} catch (error) {
console.error(`第 ${i + 1} 个元素转换失败:`, error);
results.push(null);
}
}
return results;
}
}
/**
* 便捷函数:快速转换并下载
* @param {HTMLElement} element - 要转换的HTML元素
* @param {string} filename - 文件名
* @param {Object} options - 转换选项
*/
async function convertAndDownload(element, filename = 'screenshot.png', options = {}) {
const converter = new HTMLToImage(options);
try {
const dataURL = await converter.toImage(element, options);
converter.downloadImage(dataURL, filename);
console.log('图片下载成功');
return Promise.resolve(); // 返回成功的Promise
} catch (error) {
console.error('转换下载失败:', error);
return Promise.reject(error); // 返回失败的Promise
}
}
/**
* 便捷函数:获取图片DataURL
* @param {HTMLElement} element - 要转换的HTML元素
* @param {Object} options - 转换选项
* @returns {Promise}
*/
async function getImageDataURL(element, options = {}) {
const converter = new HTMLToImage(options);
return await converter.toImage(element, options);
}
// 导出到全局作用域
if (typeof window !== 'undefined') {
window.HTMLToImage = HTMLToImage;
window.convertAndDownload = convertAndDownload;
window.getImageDataURL = getImageDataURL;
}