//import { fabric } from "fabric-with-all"; import { LayerType, OperationType, createBitmapLayer } from "./layerHelper"; // 导入新的复合命令 import { CreateImageLayerCommand } from "../commands/LayerCommands"; // 导入新的命令 import { ChangeFixedImageCommand, AddImageToLayerCommand, } from "../commands/LayerCommands"; /** * 加载并处理图片 * @param {string} imageSource - 图片URL或Base64字符串 * @param {Object} options - 配置选项 * @param {number} options.maxWidth - 最大宽度 * @param {number} options.maxHeight - 最大高度 * @param {boolean} options.centerOnCanvas - 是否居中图片 * @param {function} options.onLoad - 加载完成回调 * @returns {Promise} - 返回图片对象的Promise */ export function loadImage(imageSource, options = {}) { return new Promise((resolve, reject) => { fabric.Image.fromURL( imageSource, (fabricImage) => { if (!fabricImage) { reject(new Error("加载图片失败")); return; } // 计算缩放比例 const imgWidth = fabricImage.width; const imgHeight = fabricImage.height; // 应用缩放 if (options.maxWidth && options.maxHeight) { const scaleX = options.maxWidth / imgWidth; const scaleY = options.maxHeight / imgHeight; const scale = Math.min(scaleX, scaleY, 1); // 不超过原始大小 fabricImage.scale(scale); } // 设置图片位置 - 默认居中 if (options.centerOnCanvas !== false) { fabricImage.set({ left: (options.canvasWidth || 800) / 2, top: (options.canvasHeight || 600) / 2, originX: "center", originY: "center", selectable: true, hasControls: true, hasBorders: true, }); } // 执行加载完成回调 if (typeof options.onLoad === "function") { options.onLoad(fabricImage); } resolve(fabricImage); }, { crossOrigin: "anonymous" } ); }); } /** * 创建图片图层 * @param {Object} layerManager - 图层管理器 * @param {Object} fabricImage - fabric图片对象 * @param {Object} toolManager - 工具管理器 * @param {string} layerName - 图层名称 (可选) * @returns {Promise} 新图层ID */ export async function createImageLayer({ layerManager, fabricImage, toolManager, layerName = null, } = {}) { if (!layerManager || !fabricImage) { console.error("图层管理器或图片对象无效"); return null; } try { // 使用新的复合命令 const createImageLayerCmd = new CreateImageLayerCommand({ layerManager, fabricImage, toolManager, layerName, }); // 执行复合命令 const newLayerId = await layerManager.commandManager.execute( createImageLayerCmd ); return newLayerId; } catch (error) { console.error("创建图片图层失败:", error); throw error; } } /** * 更改固定图层的图像 * @param {Object} options - 配置选项 * @param {Object} options.layerManager - 图层管理器 * @param {string} options.fixedLayerId - 固定图层ID * @param {Object} options.fabricImage - 新的图像对象 * @returns {Promise} 是否成功更改 */ export async function changeFixedImage({ layerManager, fixedLayerId, fabricImage, } = {}) { if (!layerManager || !fixedLayerId || !fabricImage) { console.error("更改固定图层图像:参数无效"); return false; } try { // 创建更改固定图层图像命令 const changeFixedImageCmd = new ChangeFixedImageCommand({ canvas: layerManager.canvas, layers: layerManager.layers, fixedLayerId, newImage: fabricImage, layerManager, }); // 通过命令管理器执行 const result = await layerManager.commandManager.execute( changeFixedImageCmd ); if (result) { console.log(`✅ 成功更改固定图层 "${fixedLayerId}" 的图像`); } return result; } catch (error) { console.error("更改固定图层图像失败:", error); throw error; } } /** * 添加图片到指定图层或创建新图层 * @param {Object} options - 配置选项 * @param {Object} options.layerManager - 图层管理器 * @param {Object} options.toolManager - 工具管理器 * @param {Object} options.fabricImage - 图像对象 * @param {string} options.targetLayerId - 目标图层ID(可选,未指定则创建新图层) * @param {string} options.layerName - 图层名称(用于新建图层) * @returns {Promise} 图层ID */ export async function addImageToLayer({ layerManager, toolManager, fabricImage, targetLayerId = null, layerName = null, } = {}) { if (!layerManager || !fabricImage) { console.error("添加图片到图层:参数无效"); return null; } try { // 创建添加图片到图层命令 const addImageToLayerCmd = new AddImageToLayerCommand({ canvas: layerManager.canvas, layers: layerManager.layers, layerManager, toolManager, fabricImage, targetLayerId, layerName, activeLayerId: layerManager.activeLayerId, }); // 通过命令管理器执行 const resultLayerId = await layerManager.commandManager.execute( addImageToLayerCmd ); if (resultLayerId) { if (targetLayerId) { console.log(`✅ 成功添加图片到现有图层 "${targetLayerId}"`); } else { console.log(`✅ 成功创建新图层 "${resultLayerId}" 并添加图片`); } } return resultLayerId; } catch (error) { console.error("添加图片到图层失败:", error); throw error; } } /** * 从File对象加载图片并创建图层 * @param {File} file - 文件对象 * @param {Object} layerManager - 图层管理器 * @param {Object} canvas - fabric.js画布实例 * @param {Object} options - 配置选项 * @returns {Promise} 新图层ID的Promise */ export function uploadImageAndCreateLayer( { file, layerManager, canvas, toolManager }, options = {} ) { return new Promise((resolve, reject) => { if (!file || !layerManager || !canvas) { reject(new Error("参数无效")); return; } const reader = new FileReader(); reader.onload = async (e) => { try { // 查找背景图层以获取尺寸 const bgLayer = layerManager.layers.value.find( (layer) => layer.isBackground ); // 设置最大宽高为背景图层的尺寸 const maxWidth = bgLayer?.canvasWidth || canvas.width; const maxHeight = bgLayer?.canvasHeight || canvas.height; // 加载并处理图片 const fabricImage = await loadImage(e.target.result, { maxWidth: maxWidth * 0.8, // 默认图片最大宽度为背景宽度的80% maxHeight: maxHeight * 0.8, // 默认图片最大高度为背景高度的80% canvasWidth: canvas.width, canvasHeight: canvas.height, ...options, }); // 创建图片图层 const layerId = await createImageLayer({ layerManager, fabricImage, toolManager, layerName: file.name, }); resolve(layerId); } catch (error) { console.error("处理图片失败:", error); reject(error); } }; reader.onerror = (error) => { console.error("读取文件失败:", error); reject(error); }; reader.readAsDataURL(file); }); } /** * 安全加载图片 * 添加错误处理和重试机制 * @param {string} imageSource - 图片URL或Base64字符串 * @param {Object} options - 配置选项 * @returns {Promise} - 返回图片对象的Promise */ export function safeLoadImage(imageSource, options = {}) { return new Promise((resolve, reject) => { let retries = options.retries || 1; const attemptLoad = (attempt = 0) => { loadImage(imageSource, options) .then(resolve) .catch((error) => { if (attempt < retries) { console.warn( `图片加载失败,正在重试 (${attempt + 1}/${retries})...` ); setTimeout(() => attemptLoad(attempt + 1), 500); } else { reject(error); } }); }; attemptLoad(); }); } /** * 从URL加载图片并更改固定图层 * @param {Object} options - 配置选项 * @param {string} options.imageUrl - 图片URL * @param {Object} options.layerManager - 图层管理器 * @param {string} options.fixedLayerId - 固定图层ID * @param {Object} options.imageOptions - 图片加载选项 * @returns {Promise} 是否成功 */ export function loadImageAndChangeFixedLayer({ imageUrl, layerManager, fixedLayerId, imageOptions = {}, }) { return new Promise((resolve, reject) => { if (!imageUrl || !layerManager || !fixedLayerId) { reject(new Error("参数无效")); return; } loadImage(imageUrl, imageOptions) .then(async (fabricImage) => { try { const result = await changeFixedImage({ layerManager, fixedLayerId, fabricImage, }); resolve(result); } catch (error) { console.error("更改固定图层失败:", error); reject(error); } }) .catch((error) => { console.error("加载图片失败:", error); reject(error); }); }); } /** * 从File对象更改固定图层图像 * @param {Object} options - 配置选项 * @param {File} options.file - 图像文件对象 * @param {Object} options.layerManager - 图层管理器 * @param {string} options.layerId - 固定图层ID * @param {Object} options.imageOptions - 图片加载选项 * @returns {Promise} 新图像对象ID的Promise */ export function uploadImageAndChangeFixedLayer({ file, layerManager, layerId, imageOptions = {}, }) { return new Promise((resolve, reject) => { if (!file || !layerManager || !layerId) { reject(new Error("参数无效:需要文件、图层管理器和图层ID")); return; } // 验证文件类型 if (!file.type.startsWith("image/")) { reject(new Error("无效的文件类型:必须是图像文件")); return; } const reader = new FileReader(); reader.onload = async (e) => { try { // 查找目标固定图层以获取尺寸信息 const targetLayer = layerManager.layers.value.find( (layer) => layer.id === layerId ); if (!targetLayer) { throw new Error(`找不到图层 ID: ${layerId}`); } // 验证是否为固定图层 if (!targetLayer.isFixed && !targetLayer.isBackground) { throw new Error("只能更改固定图层或背景图层的图像"); } // 查找背景图层以获取画布尺寸 const bgLayer = layerManager.layers.value.find( (layer) => layer.isBackground ); const maxWidth = bgLayer?.canvasWidth || layerManager.canvas.width; const maxHeight = bgLayer?.canvasHeight || layerManager.canvas.height; // 加载并处理图片 const fabricImage = await loadImage(e.target.result, { maxWidth: maxWidth, maxHeight: maxHeight, canvasWidth: layerManager.canvas.width, canvasHeight: layerManager.canvas.height, centerOnCanvas: true, ...imageOptions, }); // 创建更改固定图层图像命令 const changeFixedImageCmd = new ChangeFixedImageCommand({ canvas: layerManager.canvas, layers: layerManager.layers, layerId: layerId, newImageFile: file, layerManager: layerManager, }); // 通过命令管理器执行 const newImageId = await layerManager.commandManager.execute( changeFixedImageCmd ); if (newImageId) { console.log( `✅ 成功更改固定图层 "${targetLayer.name}" 的图像,新图像ID: ${newImageId}` ); resolve(newImageId); } else { throw new Error("更改固定图层图像失败"); } } catch (error) { console.error("处理图片失败:", error); reject(error); } }; reader.onerror = (error) => { console.error("读取文件失败:", error); reject(new Error("文件读取失败")); }; reader.readAsDataURL(file); }); } /** * 从File对象加载图片并添加到指定图层 (简化版) * @param {Object} options - 配置选项 * @param {File} options.file - 文件对象 * @param {Object} options.layerManager - 图层管理器 * @param {Object} options.toolManager - 工具管理器 * @param {string} options.targetLayerId - 目标图层ID(可选) * @param {Object} options.imageOptions - 图片加载选项 * @returns {Promise} 返回 { layerId, imageId, wasLayerCreated } 的Promise */ export function uploadImageAndAddToLayer({ file, layerManager, toolManager, targetLayerId = null, imageOptions = {}, }) { return new Promise((resolve, reject) => { if (!file || !layerManager) { reject(new Error("参数无效:需要文件和图层管理器")); return; } // 验证文件类型 if (!file.type.startsWith("image/")) { reject(new Error("无效的文件类型:必须是图像文件")); return; } // 创建添加图像到图层命令 const addImageToLayerCmd = new AddImageToLayerCommand({ canvas: layerManager.canvas, layers: layerManager.layers, activeLayerId: layerManager.activeLayerId, imageFile: file, targetLayerId: targetLayerId, layerManager: layerManager, toolManager: toolManager, }); // 通过命令管理器执行 layerManager.commandManager .execute(addImageToLayerCmd) .then((result) => { if (result) { console.log(`✅ 成功添加图像到图层,结果:`, result); resolve(result); } else { throw new Error("添加图像到图层失败"); } }) .catch((error) => { console.error("添加图像到图层失败:", error); reject(error); }); }); } /** * 从File对象加载图片并添加到指定图层 (简化版) * @param {Object} options - 配置选项 * @param {File} options.file - 文件对象 * @param {Object} options.layerManager - 图层管理器 * @param {Object} options.toolManager - 工具管理器 * @param {string} options.targetLayerId - 目标图层ID(可选) * @param {Object} options.imageOptions - 图片加载选项 * @returns {Promise} 返回 { layerId, imageId, wasLayerCreated } 的Promise */ export function uploadImageAndAddToLayerSimple({ file, layerManager, toolManager, targetLayerId = null, imageOptions = {}, }) { return new Promise((resolve, reject) => { if (!file || !layerManager) { reject(new Error("参数无效:需要文件和图层管理器")); return; } // 验证文件类型 if (!file.type.startsWith("image/")) { reject(new Error("无效的文件类型:必须是图像文件")); return; } // 创建添加图像到图层命令 const addImageToLayerCmd = new AddImageToLayerCommand({ canvas: layerManager.canvas, layers: layerManager.layers, activeLayerId: layerManager.activeLayerId, imageFile: file, targetLayerId: targetLayerId, layerManager: layerManager, toolManager: toolManager, }); // 通过命令管理器执行 layerManager.commandManager .execute(addImageToLayerCmd) .then((result) => { if (result) { console.log(`✅ 成功添加图像到图层,结果:`, result); resolve(result); } else { throw new Error("添加图像到图层失败"); } }) .catch((error) => { console.error("添加图像到图层失败:", error); reject(error); }); }); } /** * 批量上传图片并创建图层 * @param {Object} options - 配置选项 * @param {FileList|Array} options.files - 文件列表 * @param {Object} options.layerManager - 图层管理器 * @param {Object} options.canvas - fabric.js画布实例 * @param {Object} options.toolManager - 工具管理器 * @param {Object} options.imageOptions - 图片加载选项 * @param {function} options.onProgress - 进度回调函数 * @returns {Promise>} 新图层ID数组的Promise */ export async function batchUploadImagesAndCreateLayers({ files, layerManager, canvas, toolManager, imageOptions = {}, onProgress = null, }) { if (!files || files.length === 0) { throw new Error("没有提供文件"); } if (!layerManager || !canvas) { throw new Error("缺少必要的参数:图层管理器或画布"); } const results = []; const errors = []; for (let i = 0; i < files.length; i++) { const file = files[i]; try { // 调用进度回调 if (typeof onProgress === "function") { onProgress({ current: i + 1, total: files.length, fileName: file.name, status: "processing", }); } // 验证文件类型 if (!file.type.startsWith("image/")) { console.warn(`跳过非图像文件: ${file.name}`); continue; } // 上传图片并创建图层 const layerId = await uploadImageAndCreateLayer( { file, layerManager, canvas, toolManager }, imageOptions ); results.push({ fileName: file.name, layerId: layerId, success: true, }); // 调用进度回调 if (typeof onProgress === "function") { onProgress({ current: i + 1, total: files.length, fileName: file.name, status: "success", layerId: layerId, }); } console.log(`✅ 成功处理文件: ${file.name}, 图层ID: ${layerId}`); } catch (error) { console.error(`❌ 处理文件失败: ${file.name}`, error); errors.push({ fileName: file.name, error: error.message, success: false, }); // 调用进度回调 if (typeof onProgress === "function") { onProgress({ current: i + 1, total: files.length, fileName: file.name, status: "error", error: error.message, }); } } } // 输出批量处理结果 console.log(`📊 批量处理完成:`); console.log(` ✅ 成功: ${results.length} 个文件`); console.log(` ❌ 失败: ${errors.length} 个文件`); if (errors.length > 0) { console.warn("失败的文件:", errors); } return { results: results, errors: errors, successCount: results.length, errorCount: errors.length, total: files.length, }; } /** * 高级图像管理工具 * 提供批量图像处理、缓存、预加载等高级功能 */ export class AdvancedImageManager { constructor(canvasManager) { this.canvasManager = canvasManager; this.canvas = canvasManager.canvas; this.layerManager = canvasManager.layerManager; // 图像缓存 this.imageCache = new Map(); this.preloadQueue = []; this.maxCacheSize = 50; // 最大缓存数量 // 批量操作状态 this.batchOperations = []; this.isBatchMode = false; // 性能监控 this.performanceMetrics = { imageLoads: 0, cacheHits: 0, totalLoadTime: 0, averageLoadTime: 0, }; } /** * 预加载图像列表 * @param {Array} imageUrls 要预加载的图像URL数组 * @param {Object} options 选项 */ async preloadImages(imageUrls, options = {}) { const { concurrency = 3, // 并发数量 timeout = 10000, onProgress = null, onError = null, } = options; const loadPromises = []; const results = []; let completed = 0; // 分批并发加载 for (let i = 0; i < imageUrls.length; i += concurrency) { const batch = imageUrls.slice(i, i + concurrency); const batchPromises = batch.map(async (url, index) => { try { const startTime = performance.now(); const image = await this.loadAndCacheImage(url, { timeout }); const loadTime = performance.now() - startTime; // 更新性能指标 this.updatePerformanceMetrics(loadTime); completed++; onProgress?.({ completed, total: imageUrls.length, url }); return { success: true, url, image, loadTime }; } catch (error) { completed++; onError?.({ url, error, completed, total: imageUrls.length }); return { success: false, url, error: error.message }; } }); const batchResults = await Promise.all(batchPromises); results.push(...batchResults); } return { results, summary: { total: imageUrls.length, successful: results.filter((r) => r.success).length, failed: results.filter((r) => !r.success).length, cacheHitRate: this.performanceMetrics.cacheHits / this.performanceMetrics.imageLoads, averageLoadTime: this.performanceMetrics.averageLoadTime, }, }; } /** * 加载并缓存图像 * @param {String} url 图像URL * @param {Object} options 选项 */ async loadAndCacheImage(url, options = {}) { // 检查缓存 if (this.imageCache.has(url)) { this.performanceMetrics.cacheHits++; return this.imageCache.get(url); } // 加载新图像 const image = await this.loadImage(url, options); // 添加到缓存 this.addToCache(url, image); return image; } /** * 开始批量操作模式 */ startBatch() { this.isBatchMode = true; this.batchOperations = []; } /** * 批量更换多个固定图层的图像 * @param {Array} operations 操作数组 [{layerType, imageUrl, options}, ...] */ async batchChangeFixedImages(operations) { const operationResults = []; if (this.isBatchMode) { // 如果在批量模式下,只收集操作 this.batchOperations.push( ...operations.map((op) => ({ type: "changeFixed", ...op, })) ); return { queued: operations.length }; } // 立即执行模式 for (const operation of operations) { try { const result = await this.canvasManager.changeFixedImage( operation.imageUrl, { targetLayerType: operation.layerType, ...operation.options, } ); operationResults.push({ success: true, ...result, operation }); } catch (error) { operationResults.push({ success: false, error: error.message, operation, }); } } return { results: operationResults, summary: this.getSummary(operationResults), }; } /** * 批量向多个图层添加图像 * @param {Array} operations 操作数组 [{layerId, imageUrl, position, options}, ...] */ async batchAddImagesToLayers(operations) { const operationResults = []; if (this.isBatchMode) { this.batchOperations.push( ...operations.map((op) => ({ type: "addToLayer", ...op, })) ); return { queued: operations.length }; } // 并发执行以提高性能 const concurrentOperations = operations.map(async (operation) => { try { const result = await this.canvasManager.addImageToLayer( operation.imageUrl, operation.layerId, { position: operation.position, ...operation.options, } ); return { success: true, ...result, operation }; } catch (error) { return { success: false, error: error.message, operation, }; } }); const concurrentResults = await Promise.all(concurrentOperations); return { results: concurrentResults, summary: this.getSummary(concurrentResults), }; } /** * 执行批量操作 */ async executeBatch() { if (!this.isBatchMode || this.batchOperations.length === 0) { return { message: "No batch operations to execute" }; } const results = []; const startTime = performance.now(); // 按类型分组操作以优化执行 const groupedOps = this.groupOperationsByType(this.batchOperations); // 执行分组操作 for (const [type, ops] of Object.entries(groupedOps)) { try { let typeResults; switch (type) { case "changeFixed": typeResults = await this.batchChangeFixedImages(ops); break; case "addToLayer": typeResults = await this.batchAddImagesToLayers(ops); break; default: console.warn(`Unknown operation type: ${type}`); continue; } if (typeResults.results) { results.push(...typeResults.results); } } catch (error) { console.error(`Batch execution failed for type ${type}:`, error); // 继续执行其他类型的操作 } } const executionTime = performance.now() - startTime; // 清理批量状态 this.isBatchMode = false; this.batchOperations = []; return { results, summary: { ...this.getSummary(results), executionTime, operationsPerSecond: results.length / (executionTime / 1000), }, }; } /** * 创建图像替换模板 * @param {String} templateName 模板名称 * @param {Array} operations 操作定义 */ createTemplate(templateName, operations) { if (!this.templates) { this.templates = new Map(); } this.templates.set(templateName, { name: templateName, operations, createdAt: new Date(), usageCount: 0, }); } /** * 应用模板 * @param {String} templateName 模板名称 * @param {Object} variables 变量替换映射 */ async applyTemplate(templateName, variables = {}) { const template = this.templates?.get(templateName); if (!template) { throw new Error(`Template "${templateName}" not found`); } // 替换模板中的变量 const operations = this.replaceTemplateVariables( template.operations, variables ); // 执行操作 const result = await this.batchAddImagesToLayers(operations); // 更新使用计数 template.usageCount++; return result; } /** * 智能图像优化 * @param {String} imageUrl 图像URL * @param {Object} targetSpecs 目标规格 {width, height, quality} */ async optimizeImage(imageUrl, targetSpecs) { const image = await this.loadAndCacheImage(imageUrl); // 检查是否需要优化 const currentSpecs = { width: image.width, height: image.height, }; if (this.shouldOptimize(currentSpecs, targetSpecs)) { return this.performImageOptimization(image, targetSpecs); } return image; } /** * 清理缓存 * @param {String} strategy 清理策略 'lru', 'size', 'all' */ clearCache(strategy = "lru") { switch (strategy) { case "all": this.imageCache.clear(); break; case "size": if (this.imageCache.size > this.maxCacheSize) { const excess = this.imageCache.size - this.maxCacheSize; const keys = Array.from(this.imageCache.keys()); for (let i = 0; i < excess; i++) { this.imageCache.delete(keys[i]); } } break; case "lru": // 实现 LRU 清理逻辑 this.implementLRUCleanup(); break; } } // === 私有方法 === loadImage(url, options = {}) { return new Promise((resolve, reject) => { const timeout = setTimeout(() => { reject(new Error(`Image load timeout: ${url}`)); }, options.timeout || 10000); fabric.Image.fromURL( url, (img) => { clearTimeout(timeout); if (!img || !img.getElement()) { reject(new Error("Invalid image")); return; } resolve(img); }, { crossOrigin: "anonymous" } ); }); } addToCache(url, image) { // 检查缓存大小限制 if (this.imageCache.size >= this.maxCacheSize) { this.clearCache("size"); } // 添加时间戳用于 LRU const cacheEntry = { image, lastUsed: Date.now(), usageCount: 1, }; this.imageCache.set(url, cacheEntry); } updatePerformanceMetrics(loadTime) { this.performanceMetrics.imageLoads++; this.performanceMetrics.totalLoadTime += loadTime; this.performanceMetrics.averageLoadTime = this.performanceMetrics.totalLoadTime / this.performanceMetrics.imageLoads; } getSummary(results) { return { total: results.length, successful: results.filter((r) => r.success).length, failed: results.filter((r) => !r.success).length, successRate: results.filter((r) => r.success).length / results.length, }; } groupOperationsByType(operations) { return operations.reduce((groups, op) => { const type = op.type; if (!groups[type]) groups[type] = []; groups[type].push(op); return groups; }, {}); } replaceTemplateVariables(operations, variables) { return operations.map((op) => { const newOp = { ...op }; // 替换字符串中的变量 {{variable}} Object.keys(newOp).forEach((key) => { if (typeof newOp[key] === "string") { newOp[key] = newOp[key].replace( /\{\{(\w+)\}\}/g, (match, varName) => { return variables[varName] || match; } ); } }); return newOp; }); } shouldOptimize(current, target) { const sizeThreshold = 0.8; // 80% 的阈值 return ( current.width > target.width * (1 / sizeThreshold) || current.height > target.height * (1 / sizeThreshold) ); } performImageOptimization(image, targetSpecs) { // 实现图像优化逻辑 // 这里可以集成图像压缩、尺寸调整等功能 return image; // 简化实现 } implementLRUCleanup() { if (this.imageCache.size <= this.maxCacheSize) return; // 按最后使用时间排序,移除最久未使用的 const entries = Array.from(this.imageCache.entries()).sort( (a, b) => a[1].lastUsed - b[1].lastUsed ); const toRemove = entries.slice(0, this.imageCache.size - this.maxCacheSize); toRemove.forEach(([key]) => this.imageCache.delete(key)); } // 获取性能报告 getPerformanceReport() { return { ...this.performanceMetrics, cacheSize: this.imageCache.size, maxCacheSize: this.maxCacheSize, cacheUtilization: this.imageCache.size / this.maxCacheSize, recommendations: this.generatePerformanceRecommendations(), }; } generatePerformanceRecommendations() { const recommendations = []; if ( this.performanceMetrics.cacheHits / this.performanceMetrics.imageLoads < 0.3 ) { recommendations.push("考虑增加缓存大小以提高缓存命中率"); } if (this.performanceMetrics.averageLoadTime > 2000) { recommendations.push("图像加载时间较长,考虑图像优化或CDN"); } return recommendations; } } /** * 图像工具集 * 提供常用的图像处理和图层操作功能 */ export const ImageUtils = { // 基础图像加载 loadImage, safeLoadImage, // 图层操作 createImageLayer, changeFixedImage, addImageToLayer, // 文件上传处理 uploadImageAndCreateLayer, uploadImageAndChangeFixedLayer, uploadImageAndAddToLayer, uploadImageAndAddToLayerSimple, batchUploadImagesAndCreateLayers, // URL图像处理 loadImageAndChangeFixedLayer, /** * 快速创建图像图层 (别名) * @param {File} file - 图像文件 * @param {Object} layerManager - 图层管理器 * @param {Object} canvas - 画布实例 * @param {Object} toolManager - 工具管理器 * @returns {Promise} 图层ID */ quickCreateImageLayer: (file, layerManager, canvas, toolManager) => { return uploadImageAndCreateLayer({ file, layerManager, canvas, toolManager, }); }, /** * 快速更改固定图层图像 (别名) * @param {File} file - 图像文件 * @param {string} layerId - 图层ID * @param {Object} layerManager - 图层管理器 * @returns {Promise} 新图像ID */ quickChangeFixedImage: (file, layerId, layerManager) => { return uploadImageAndChangeFixedLayer({ file, layerId, layerManager }); }, /** * 快速添加图像到图层 (别名) * @param {File} file - 图像文件 * @param {Object} layerManager - 图层管理器 * @param {Object} toolManager - 工具管理器 * @param {string} targetLayerId - 目标图层ID (可选) * @returns {Promise} 执行结果 */ quickAddImageToLayer: ( file, layerManager, toolManager, targetLayerId = null ) => { return uploadImageAndAddToLayerSimple({ file, layerManager, toolManager, targetLayerId, }); }, };