From 63bb46ea475eb27352b7e2099db5220993a09976 Mon Sep 17 00:00:00 2001 From: knowen <1369727119@qq.com> Date: Wed, 18 Mar 2026 20:55:25 +0800 Subject: [PATCH] =?UTF-8?q?feat(demo):=20=E6=B7=BB=E5=8A=A0=E5=9B=BE?= =?UTF-8?q?=E7=89=87=E5=8A=A0=E8=BD=BD=E5=AE=8C=E6=88=90=E6=A3=80=E6=B5=8B?= =?UTF-8?q?=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/demo.js | 31 +++++++++++++++++++++---------- src/gemini-ops.js | 31 ++++++++++++++++++++++++++++++- 2 files changed, 51 insertions(+), 11 deletions(-) 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)); }