/** * Qwen Image Editor API 封装 * 参考 qwen-image.js 的实现风格 */ class QwenImageEditor { constructor() { this.baseUrl = '/api/qwenImage'; this.editUrl = `${this.baseUrl}/edit`; this.initEventListeners(); // 初始化时渲染示例 this.renderExamples(); } /** * 初始化事件监听 */ initEventListeners() { // 移除Layui依赖,使用原生JS实现 document.getElementById('startEditBtn').addEventListener('click', () => this.handleEditSubmit()); // 删除JS动态创建按钮的代码 // 直接绑定静态按钮事件 document.getElementById('randomExampleBtn').addEventListener('click', () => this.handleRandomExample()); } /** * 处理编辑表单提交 */ handleEditSubmit() { const imageUrl = document.getElementById('imageUrl').value; const prompt = document.getElementById('editPrompt').value; const size = document.getElementById('editSize').value; const style = document.getElementById('editStyle').value; if (!imageUrl || !prompt) { alert('图片URL和编辑提示词不能为空'); return; } const loadingIndicator = document.createElement('div'); loadingIndicator.className = 'fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50'; loadingIndicator.innerHTML = ''; document.body.appendChild(loadingIndicator); // 显示原始图片 document.getElementById('originalImage').src = imageUrl; document.getElementById('originalImage').classList.remove('hidden'); document.getElementById('originalImagePlaceholder').classList.add('hidden'); // 调用编辑接口 this.editImage(imageUrl, prompt, size, style) .then(result => { document.body.removeChild(loadingIndicator); document.getElementById('editedImage').src = result.edited_image; document.getElementById('editedImage').classList.remove('hidden'); document.getElementById('editedImagePlaceholder').classList.add('hidden'); alert('编辑成功'); }) .catch(error => { document.body.removeChild(loadingIndicator); alert(`编辑失败: ${error.message || '网络请求错误'}`); }); } /** * 调用图片编辑接口 * @param {string} imageUrl - 原始图片URL * @param {string} prompt - 编辑提示词 * @param {string} size - 图像尺寸 * @param {string} style - 艺术风格 * @returns {Promise} - 编辑结果 */ async editImage(imageUrl, prompt, size, style) { try { const response = await axios.post(this.editUrl, { image_url: imageUrl, prompt: prompt, size: size, style: style }); if (response.data.code !== 200) { throw new Error(response.data.message || '编辑接口返回错误'); } return response.data.data; } catch (error) { console.error('图片编辑失败:', error); throw error.response?.data || { message: '网络请求失败,请重试' }; } } /** * 渲染示例区域 */ renderExamples() { // 统一示例数据结构 const exampleGroups = [ { id: 'bearExamples', title: '小熊系列', aspectRatio: '1/1', // 新增:小熊系列方形比例 originalImage: 'https://help-static-aliyun-doc.aliyuncs.com/assets/img/zh-CN/7219965571/p999719.png', examples: [ { prompt: '这只熊拿着五彩画板和画笔,站在画板前画画', resultImage: 'https://help-static-aliyun-doc.aliyuncs.com/assets/img/zh-CN/7219965571/p999625.png' }, { prompt: '这只熊站在白色背景前,手里拿着锅铲,旁边有蔬菜和调料', resultImage: 'https://help-static-aliyun-doc.aliyuncs.com/assets/img/zh-CN/7219965571/p999626.png' }, { prompt: '这只熊坐在地上,怀里抱着一把吉他,手指拨动琴弦', resultImage: 'https://help-static-aliyun-doc.aliyuncs.com/assets/img/zh-CN/7219965571/p999628.png' }, { prompt: '这只熊穿着燕尾服,戴着魔术帽,手里拿着魔术棒,做出表演魔术的动作', resultImage: 'https://help-static-aliyun-doc.aliyuncs.com/assets/img/zh-CN/7219965571/p999629.png' }, { prompt: '这只熊穿着运动服,手里拿着篮球,单腿弯曲', resultImage: 'https://help-static-aliyun-doc.aliyuncs.com/assets/img/zh-CN/7219965571/p999630.png' }, { prompt: '这只熊戴着草帽,手里拿着花洒和小铲子,正在浇水或种植植物', resultImage: 'https://help-static-aliyun-doc.aliyuncs.com/assets/img/zh-CN/7219965571/p999631.png' }, // 添加缺失的5个示例 {prompt: '这只熊穿着宇航服,伸出手指向远方', resultImage: 'https://help-static-aliyun-doc.aliyuncs.com/assets/img/zh-CN/7219965571/p999632.png'}, {prompt: '这只熊穿着华丽的舞裙,双臂展开,做出优雅的舞蹈动作', resultImage: 'https://help-static-aliyun-doc.aliyuncs.com/assets/img/zh-CN/7219965571/p999633.png'}, {prompt: '把背景改成草原', resultImage: 'https://help-static-aliyun-doc.aliyuncs.com/assets/img/zh-CN/7219965571/p1000045.png'}, {prompt: '给它戴上红色帽子和黑色墨镜', resultImage: 'https://help-static-aliyun-doc.aliyuncs.com/assets/img/zh-CN/7219965571/p1000051.png'}, {prompt: '改成梵高油画风格', resultImage: 'https://help-static-aliyun-doc.aliyuncs.com/assets/img/zh-CN/7219965571/p1000061.png'} ] }, { id: 'hanfuExamples', title: '霓裳汉服社系列', aspectRatio: '5/7', // 新增:汉服社系列5:7比例 originalImage: 'https://help-static-aliyun-doc.aliyuncs.com/assets/img/zh-CN/7219965571/p1000025.png', examples: [ { prompt: '把“霓裳汉服社”改成“通义实验室”', resultImage: 'https://help-static-aliyun-doc.aliyuncs.com/assets/img/zh-CN/7219965571/p1000026.png' }, { prompt: '把“活动全程免费”改为“只给学生打折”', resultImage: 'https://help-static-aliyun-doc.aliyuncs.com/assets/img/zh-CN/7219965571/p1000027.png' }, { prompt: '把女人改成穿汉服的男人', resultImage: 'https://help-static-aliyun-doc.aliyuncs.com/assets/img/zh-CN/7219965571/p1000028.png' } ] } ]; // 新增:保存示例数据到实例属性 this.exampleGroups = exampleGroups; this.allExamples = []; // 渲染每个系列的示例并收集所有示例 exampleGroups.forEach(group => { const container = document.getElementById(group.id); if (!container) return; container.innerHTML = ''; group.examples.forEach(example => { // 收集所有示例用于随机选择 this.allExamples.push({ originalImage: group.originalImage, prompt: example.prompt, resultImage: example.resultImage }); container.appendChild(this.createExampleCard( group.originalImage, example.prompt, example.resultImage, group.aspectRatio )); }); }); // 新增:自动选择小熊系列第一个示例 setTimeout(() => { const bearContainer = document.getElementById('bearExamples'); if (bearContainer && bearContainer.firstElementChild) { bearContainer.firstElementChild.click(); } }, 100); } /** * 创建示例卡片 * @param {string} originalImage - 原始图片URL * @param {string} prompt - 编辑提示词 * @param {string} resultImage - 结果图片URL * @param {string} aspectRatio - 宽高比(新增参数) * @returns {HTMLElement} - 卡片元素 */ createExampleCard(originalImage, prompt, resultImage, aspectRatio) { const card = document.createElement('div'); card.className = 'example-card bg-white dark:bg-gray-800 rounded-xl shadow-lg overflow-hidden transition-all duration-300 hover:shadow-xl cursor-pointer'; card.innerHTML = `
${prompt.substring(0, 20)}...

${prompt}

`; // 点击事件 - 加载原图和填充表单 card.addEventListener('click', () => { // 填充表单 document.getElementById('imageUrl').value = originalImage; document.getElementById('editPrompt').value = prompt; // 更新原始图片预览 const originalImageElement = document.getElementById('originalImage'); const originalImagePlaceholder = document.getElementById('originalImagePlaceholder'); originalImageElement.src = originalImage; originalImageElement.classList.remove('hidden'); originalImagePlaceholder.classList.add('hidden'); // 添加选中效果 document.querySelectorAll('.example-card').forEach(c => c.classList.remove('ring-2', 'ring-primary')); card.classList.add('ring-2', 'ring-primary'); }); return card; } /** * 随机选择一个示例并填充表单 */ handleRandomExample() { if (!this.allExamples || this.allExamples.length === 0) { alert('没有可用的示例数据'); return; } // 随机选择一个示例 const randomIndex = Math.floor(Math.random() * this.allExamples.length); const randomExample = this.allExamples[randomIndex]; // 填充表单数据 document.getElementById('imageUrl').value = randomExample.originalImage; document.getElementById('editPrompt').value = randomExample.prompt; // 更新原始图片预览 const originalImage = document.getElementById('originalImage'); const originalPlaceholder = document.getElementById('originalImagePlaceholder'); originalImage.src = randomExample.originalImage; originalImage.classList.remove('hidden'); originalPlaceholder.classList.add('hidden'); // 移除所有卡片选中状态 document.querySelectorAll('.example-card').forEach(card => { card.classList.remove('ring-2', 'ring-primary'); }); } } // 页面加载完成后初始化 document.addEventListener('DOMContentLoaded', () => new QwenImageEditor());