diff --git a/src/demo.js b/src/demo.js index 3bf2442..a1f39a5 100644 --- a/src/demo.js +++ b/src/demo.js @@ -20,7 +20,7 @@ import { writeFileSync, mkdirSync, existsSync } from 'node:fs'; import { join } from 'node:path'; import { createGeminiSession, disconnect } from './index.js'; -const prompt = 'Gemini你好!请你调用画图模型给我画一张洛天依的可爱Q版表情包~'; +const prompt = 'Gemini你好!请你仿造这个风格,给我生成更多表情包吧!来一张玩手机中。。。'; // ── Demo 专用:杀掉所有 Chromium 系浏览器进程 ── function killAllBrowserProcesses() { @@ -130,7 +130,7 @@ async function main() { // 4. 上传图片 console.log('\n[4] 上传图片...'); - const uploadResult = await ops.uploadImage('./gemini-image/tianyi.jpg'); + const uploadResult = await ops.uploadImage('./gemini-image/miku_fighting.jpg'); if (uploadResult.ok) { console.log(`[4] ✅ 图片上传完成 (${uploadResult.elapsed}ms)`); if (uploadResult.warning) console.warn(`[4] ⚠ ${uploadResult.warning}`); @@ -148,18 +148,29 @@ async function main() { }); console.log('result:', JSON.stringify(result, null, 2)); - // 6. 获取最新图片并保存到本地 + // 6. 等待图片加载完成 if (result.ok) { - console.log('\n[6] 查找最新生成的图片...'); + console.log('\n[6] 等待图片加载完成...'); + const imgLoadStart = Date.now(); + while (Date.now() - imgLoadStart < 30_000) { + const { loaded } = await ops.checkImageLoaded(); + if (loaded) break; + console.log(' 图片加载中...'); + await sleep(500); + } + console.log(`[6] 图片加载完成 (${Date.now() - imgLoadStart}ms)`); + + // 7. 获取最新图片并保存到本地 + console.log('\n[7] 查找最新生成的图片...'); const imgInfo = await ops.getLatestImage(); console.log('imgInfo:', JSON.stringify(imgInfo, null, 2)); if (imgInfo.ok && imgInfo.src) { - console.log(`[6] 找到图片 (${imgInfo.width}x${imgInfo.height}, isNew=${imgInfo.isNew})`); + console.log(`[7] 找到图片 (${imgInfo.width}x${imgInfo.height}, isNew=${imgInfo.isNew})`); // 提取 base64 数据 - console.log(`[6] 提取图片数据 (src=${imgInfo.src})...`); + console.log(`[7] 提取图片数据 (src=${imgInfo.src})...`); const b64Result = await ops.extractImageBase64(imgInfo.src); if (b64Result.ok && b64Result.dataUrl) { @@ -179,15 +190,15 @@ async function main() { const filepath = join(outputDir, filename); writeFileSync(filepath, buffer); - console.log(`[6] ✅ 图片已保存: ${filepath} (${(buffer.length / 1024).toFixed(1)} KB, method=${b64Result.method})`); + console.log(`[7] ✅ 图片已保存: ${filepath} (${(buffer.length / 1024).toFixed(1)} KB, method=${b64Result.method})`); } else { - console.warn('[6] ⚠ dataUrl 格式无法解析'); + console.warn('[7] ⚠ dataUrl 格式无法解析'); } } else { - console.warn(`[6] ⚠ 提取图片数据失败: ${b64Result.error || 'unknown'}`); + console.warn(`[7] ⚠ 提取图片数据失败: ${b64Result.error || 'unknown'}`); } } else { - console.log('[6] 未找到图片(可能本次回答不含图片)'); + console.log('[7] 未找到图片(可能本次回答不含图片)'); } } diff --git a/src/gemini-ops.js b/src/gemini-ops.js index 6b03f22..ef352fe 100644 --- a/src/gemini-ops.js +++ b/src/gemini-ops.js @@ -440,6 +440,19 @@ export function createOps(page) { return { ...status, pageVisible, ts: Date.now() }; }, + /** + * 检查生成的图片是否加载完成 + * + * 通过检测页面中 div.loader.animate 元素判断: + * 存在 → 图片还在加载中 + * 不存在 → 加载完毕 + * + * @returns {Promise<{loaded: boolean}>} + */ + async checkImageLoaded() { + return isImageLoaded(op); + }, + /** * 获取本次会话中所有已加载的图片 * @@ -736,7 +749,7 @@ export function createOps(page) { const loadTimeout = 10_000; const loadInterval = 250; const loadStart = Date.now(); - + await sleep(500); // 短暂等待 UI 响应 while (Date.now() - loadStart < loadTimeout) { const loading = await op.query(() => { const el = document.querySelector('.image-preview.loading'); @@ -888,6 +901,22 @@ function isSidebarExpanded(op) { }, SELECTORS.sidebarContainer); } +/** + * 检查生成的图片是否加载完成 + * + * 判断依据:页面中是否存在 div.loader.animate 元素。 + * 存在 → 图片还在加载;不存在 → 加载完毕。 + * + * @param {ReturnType} op + * @returns {Promise<{loaded: boolean}>} + */ +function isImageLoaded(op) { + return op.query(() => { + const loader = document.querySelector('div.loader.animate'); + return { loaded: !loader }; + }); +} + function sleep(ms) { return new Promise(r => setTimeout(r, ms)); }