Files
SmartChat/static/js/h2p.js
2026-01-08 01:06:27 +08:00

182 lines
5.6 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* 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<string>} - 返回图片的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<string>} - 返回图片的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<Blob>}
*/
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<string[]>} - 返回图片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<string>}
*/
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;
}