feat: P0-8 照片式AI炫图(7场景/纯前端合成/光照匹配)
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
// 照片式 AI 炫图端到端验证: 注入程序化测试照片 → 拖框 → 生成 → 截画廊
|
||||
// 用法: node verify-photorender.mjs <token>
|
||||
import puppeteer from 'puppeteer-core'
|
||||
const browser = await puppeteer.launch({
|
||||
executablePath: 'C:/Program Files (x86)/Microsoft/Edge/Application/msedge.exe',
|
||||
headless: 'new',
|
||||
args: ['--window-size=1440,900', '--enable-unsafe-swiftshader'],
|
||||
defaultViewport: { width: 1440, height: 900 },
|
||||
})
|
||||
const page = await browser.newPage()
|
||||
page.on('pageerror', e => console.log(`[JS异常] ${String(e).slice(0, 200)}`))
|
||||
const token = process.argv[2]
|
||||
await page.goto(`http://localhost:8000/ai_render?token=${encodeURIComponent(token)}`, { waitUntil: 'networkidle2' })
|
||||
await new Promise(r => setTimeout(r, 2000))
|
||||
|
||||
// 1) 选第一个样板
|
||||
await page.click('.controls .el-select')
|
||||
await new Promise(r => setTimeout(r, 800))
|
||||
const opt = await page.$('.el-select-dropdown__item')
|
||||
await opt.click()
|
||||
await new Promise(r => setTimeout(r, 1200))
|
||||
|
||||
// 2) 程序化生成"室内照片"并注入 el-upload
|
||||
await page.evaluate(() => {
|
||||
const cv = document.createElement('canvas')
|
||||
cv.width = 1200; cv.height = 800
|
||||
const ctx = cv.getContext('2d')
|
||||
// 墙面渐变 + 地板 + 侧窗阴影区
|
||||
const g = ctx.createLinearGradient(0, 0, 0, 800)
|
||||
g.addColorStop(0, '#e8e0d2'); g.addColorStop(0.7, '#d8cdbb'); g.addColorStop(1, '#9c8b74')
|
||||
ctx.fillStyle = g; ctx.fillRect(0, 0, 1200, 800)
|
||||
ctx.fillStyle = 'rgba(120,100,80,0.25)'
|
||||
ctx.fillRect(380, 260, 440, 340) // 旧窗洞(深色)
|
||||
ctx.strokeStyle = 'rgba(90,70,50,0.5)'; ctx.lineWidth = 8
|
||||
ctx.strokeRect(380, 260, 440, 340)
|
||||
return new Promise(resolve => {
|
||||
cv.toBlob(blob => {
|
||||
const dt = new DataTransfer()
|
||||
dt.items.add(new File([blob], 'room.png', { type: 'image/png' }))
|
||||
const input = document.querySelector('.el-upload input[type=file]')
|
||||
input.files = dt.files
|
||||
input.dispatchEvent(new Event('change'))
|
||||
resolve()
|
||||
}, 'image/png')
|
||||
})
|
||||
})
|
||||
await new Promise(r => setTimeout(r, 1200))
|
||||
|
||||
// 3) 在照片上拖框(对应旧窗洞位置)
|
||||
const stage = await page.$('.photo-cv')
|
||||
if (!stage) { console.log('✗ 照片舞台未出现'); process.exit(1) }
|
||||
const b = await stage.boundingBox()
|
||||
await page.mouse.move(b.x + b.width * 0.3, b.y + b.height * 0.3)
|
||||
await page.mouse.down()
|
||||
await page.mouse.move(b.x + b.width * 0.7, b.y + b.height * 0.75, { steps: 8 })
|
||||
await page.mouse.up()
|
||||
await new Promise(r => setTimeout(r, 400))
|
||||
|
||||
// 4) 生成
|
||||
const genBtn = await page.evaluateHandle(() => [...document.querySelectorAll('button')].find(x => x.textContent.includes('生成炫图')))
|
||||
await genBtn.asElement().click()
|
||||
await new Promise(r => setTimeout(r, 6000))
|
||||
|
||||
const shots = await page.$$('.shot')
|
||||
console.log(`方案数: ${shots.length}`)
|
||||
if (!shots.length) { console.log('✗ 未生成方案'); process.exit(1) }
|
||||
await page.evaluate(() => document.querySelector('.gallery')?.scrollIntoView({ block: 'center' }))
|
||||
await new Promise(r => setTimeout(r, 500))
|
||||
if (shots[0]) await shots[0].screenshot({ path: 'D:/Code/huamenchuang/shots/verify-photorender-0.png' })
|
||||
if (shots[1]) await shots[1].screenshot({ path: 'D:/Code/huamenchuang/shots/verify-photorender-1.png' })
|
||||
if (shots[2]) await shots[2].screenshot({ path: 'D:/Code/huamenchuang/shots/verify-photorender-2.png' })
|
||||
const stageEl = await page.$('.photo-cv')
|
||||
if (stageEl) await stageEl.screenshot({ path: 'D:/Code/huamenchuang/shots/verify-photo-stage.png' })
|
||||
console.log('✓ 照片合成炫图验证完成')
|
||||
await browser.close()
|
||||
Reference in New Issue
Block a user