优化为4b 模型
This commit is contained in:
@@ -53,11 +53,11 @@
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1>接口12 — 发际线带重绘 <span style="font-size:13px;color:#888">(final + 纯红遮罩 → 外部 ComfyUI 重绘)</span></h1>
|
||||
<h1>接口12 — 发际线带重绘 <span style="font-size:13px;color:#888">(final + 纯红遮罩 → ComfyUI 重绘)</span></h1>
|
||||
<div class="subtitle">
|
||||
内部先跑<b>接口11</b>拿到 ④接缝融合最终图(final),再取 <b>⑤-① 发际线重绘带</b>(发际线外推 band_lo_mult×push ~ band_hi_mult×push、经 baseline 截断只留上部)生成
|
||||
<b>纯红遮罩 PNG</b>(遮罩区=(255,0,0,255),其余全透明)。<br>
|
||||
前端拿到 final + 遮罩后,调 <b>外部重绘服务(local_test,默认 :8899)</b>完成重绘。⚠️ 需 ComfyUI(:8188) 在跑。
|
||||
前端拿到 final + 遮罩后,调 <b>后端重绘接口(/api/v1/redraw)</b>完成重绘。⚠️ 需 ComfyUI(:8188) 在跑。
|
||||
对照仅生成不重绘:<a href="/static/test_interface11_debug.html">接口11 调试页</a>。
|
||||
</div>
|
||||
|
||||
@@ -65,11 +65,7 @@
|
||||
<div class="upload-row">
|
||||
<input type="file" id="imageFile" accept="image/*">
|
||||
<button class="btn btn-primary" id="submitBtn" onclick="submitTest()">🎨 生成 final+遮罩</button>
|
||||
<button class="btn btn-green" id="redrawBtn" onclick="runLocalRedraw()" disabled>🧪 调 local_test 重绘</button>
|
||||
</div>
|
||||
<div class="upload-row" style="margin-top:10px">
|
||||
<label style="font-size:13px;font-weight:600;white-space:nowrap">重绘服务地址</label>
|
||||
<input type="text" id="localTestUrl" value="http://10.60.74.221:8899" style="flex:1;min-width:200px;padding:8px;border:1px solid #ddd;border-radius:8px">
|
||||
<button class="btn btn-green" id="redrawBtn" onclick="runLocalRedraw()" disabled>🧪 重绘</button>
|
||||
</div>
|
||||
<div class="upload-row" style="margin-top:10px">
|
||||
<label style="font-size:13px;font-weight:600;white-space:nowrap">重绘提示词</label>
|
||||
@@ -144,9 +140,9 @@
|
||||
<div class="steps" style="grid-template-columns: repeat(auto-fill, minmax(300px, 1fr))">
|
||||
<div class="step big"><div class="cap">接口11 final <small>④ 接缝融合(重绘输入基底,无美颜)</small></div><img id="finalBase"></div>
|
||||
<div class="step big"><div class="cap">⑤-① 发际线重绘带遮罩 <small>纯红 alpha PNG(遮罩区=红+不透明,其余全透明)</small></div><img id="maskPng"></div>
|
||||
<div class="step big"><div class="cap">🧪 local_test 重绘结果 <small>final + 遮罩 → 外部 ComfyUI(0716add-hair.json)</small></div><img id="localResult"></div>
|
||||
<div class="step big"><div class="cap">🧪 重绘结果 <small>final + 遮罩 → ComfyUI(0716add-hair)</small></div><img id="localResult"></div>
|
||||
</div>
|
||||
<div style="font-size:12px;color:#888;margin-top:10px">流程:后端产出 final(接缝融合基底)+ 纯红遮罩 PNG,前端把两者 POST 到 local_test 重绘服务完成发际线补发。</div>
|
||||
<div style="font-size:12px;color:#888;margin-top:10px">流程:后端产出 final(接缝融合基底)+ 纯红遮罩 PNG,再调后端 /api/v1/redraw 完成发际线补发。</div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
@@ -191,10 +187,10 @@ const STEPS = [
|
||||
{ key: 'input', title: '原图', sub: '接口输入' },
|
||||
{ key: 'final', title: '接口11 ④ final', sub: '接缝融合最终图(重绘输入基底,无美颜)' },
|
||||
{ key: 'redraw_band_overlay', title: '⑤-① 发际线重绘带', sub: '紫=lo×push↔hi×push之间、经 baseline 截断只留上部' },
|
||||
{ key: 'redraw_band_mask', title: '⑤-② 纯红遮罩 PNG', sub: '遮罩区=(255,0,0,255)、其余全透明;交给 local_test' },
|
||||
{ key: 'redraw_band_mask', title: '⑤-② 纯红遮罩 PNG', sub: '遮罩区=(255,0,0,255)、其余全透明;交给后端重绘' },
|
||||
];
|
||||
|
||||
// 缓存最近一次后端返回的 final(JPG data URI)和纯红遮罩(PNG data URI),供 local_test 重绘使用
|
||||
// 缓存最近一次后端返回的 final(JPG data URI)和纯红遮罩(PNG data URI),供重绘使用
|
||||
let _finalDataUri = '';
|
||||
let _maskDataUri = '';
|
||||
|
||||
@@ -237,7 +233,7 @@ function renderResult(d) {
|
||||
flog(' 渲染 ' + st.key + ': ' + (hasImg ? '有图(' + src.length + '字符)' : '无图'), hasImg ? 'info' : 'warn');
|
||||
grid.appendChild(stepCard(st.title, st.sub, src));
|
||||
});
|
||||
// final + 遮罩 都有 → 允许调 local_test 重绘
|
||||
// final + 遮罩 都有 → 允许调后端重绘
|
||||
const canRedraw = !!(finalSrc && maskSrc);
|
||||
$('redrawBtn').disabled = !canRedraw;
|
||||
flog('renderResult 完成 canRedraw=' + canRedraw, 'info');
|
||||
@@ -346,7 +342,7 @@ async function submitTest() {
|
||||
}
|
||||
}
|
||||
|
||||
// data URI → Blob,用于把后端返回的 final/遮罩图作为文件 POST 给 local_test
|
||||
// data URI → Blob,用于把后端返回的 final/遮罩图作为文件 POST 给后端重绘
|
||||
function dataUriToBlob(dataUri) {
|
||||
const [meta, b64] = dataUri.split(',');
|
||||
const mime = (meta.match(/data:([^;]+)/) || [, 'application/octet-stream'])[1];
|
||||
@@ -358,44 +354,39 @@ function dataUriToBlob(dataUri) {
|
||||
|
||||
async function runLocalRedraw() {
|
||||
if (!_finalDataUri || !_maskDataUri) { setStatus('缺少 final 或遮罩,请先生成', 'error'); return; }
|
||||
const base = $('localTestUrl').value.trim().replace(/\/+$/, '');
|
||||
if (!base) { setStatus('请填写重绘服务地址', 'error'); return; }
|
||||
const prompt = $('localTestPrompt').value.trim() || '填充遮罩区域的头发,皮肤加一点磨皮';
|
||||
const btn = $('redrawBtn');
|
||||
btn.disabled = true; btn.textContent = '⏳ 重绘中...';
|
||||
flog('===== 调 local_test 重绘 =====', 'info');
|
||||
flog('服务地址=' + base + ' 提示词=' + prompt, 'info');
|
||||
flog('===== 调后端重绘 =====', 'info');
|
||||
flog('提示词=' + prompt, 'info');
|
||||
|
||||
const form = new FormData();
|
||||
form.append('image', dataUriToBlob(_finalDataUri), 'final.jpg');
|
||||
form.append('mask', dataUriToBlob(_maskDataUri), 'mask.png');
|
||||
form.append('image_file', dataUriToBlob(_finalDataUri), 'final.jpg');
|
||||
form.append('mask_file', dataUriToBlob(_maskDataUri), 'mask.png');
|
||||
form.append('prompt', prompt);
|
||||
|
||||
const t0 = performance.now();
|
||||
try {
|
||||
flog('fetch POST ' + base + '/api/generate', 'info');
|
||||
const resp = await fetch(base + '/api/generate', { method: 'POST', body: form });
|
||||
flog('收到响应 http=' + resp.status + ' type=' + resp.headers.get('content-type'), resp.ok ? 'info' : 'error');
|
||||
flog('fetch POST ' + API_BASE + '/api/v1/redraw', 'info');
|
||||
const resp = await fetch(API_BASE + '/api/v1/redraw', { method: 'POST', body: form });
|
||||
flog('收到响应 http=' + resp.status, resp.ok ? 'info' : 'error');
|
||||
const dt = ((performance.now() - t0) / 1000).toFixed(2);
|
||||
if (resp.ok && resp.headers.get('content-type', '').includes('image/')) {
|
||||
const blob = await resp.blob();
|
||||
const url = URL.createObjectURL(blob);
|
||||
$('localResult').src = url;
|
||||
const json = await resp.json();
|
||||
if (json.code === 0 && json.data && json.data.image_base64) {
|
||||
$('localResult').src = json.data.image_base64;
|
||||
$('localResult').onclick = function(){ zoom(this.src); };
|
||||
setStatus('✅ local_test 重绘完成 (' + dt + 's)', 'success');
|
||||
flog('local_test 重绘完成 耗时=' + dt + 's 大小=' + blob.size + 'B', 'info');
|
||||
setStatus('✅ 重绘完成 (' + dt + 's)', 'success');
|
||||
flog('重绘完成 耗时=' + dt + 's', 'info');
|
||||
} else {
|
||||
// 非图片响应 → 多半是 JSON 错误
|
||||
let msg = resp.status + '';
|
||||
try { const j = await resp.json(); msg = j.error || JSON.stringify(j); } catch (_) {}
|
||||
setStatus('❌ local_test 重绘失败:' + msg, 'error');
|
||||
flog('local_test 重绘失败: ' + msg, 'error');
|
||||
const msg = json.message || JSON.stringify(json);
|
||||
setStatus('❌ 重绘失败:' + msg, 'error');
|
||||
flog('重绘失败: ' + msg, 'error');
|
||||
}
|
||||
} catch (err) {
|
||||
setStatus('❌ local_test 网络错误:' + err.message + '(确认服务在跑且已加 CORS)', 'error');
|
||||
flog('local_test 网络错误: ' + err.message, 'error');
|
||||
setStatus('❌ 重绘网络错误:' + err.message, 'error');
|
||||
flog('重绘网络错误: ' + err.message, 'error');
|
||||
} finally {
|
||||
btn.disabled = false; btn.textContent = '🧪 调 local_test 重绘';
|
||||
btn.disabled = false; btn.textContent = '🧪 重绘';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -426,8 +417,8 @@ async function downloadBackendLog() {
|
||||
|
||||
$('imageFile').addEventListener('change', function(){ if(this.files.length) flog('选择图片: ' + this.files[0].name, 'info'); });
|
||||
|
||||
flog('接口12 重绘测试页加载完成(后端产出 final+纯红遮罩 → 前端调 local_test 重绘)', 'info');
|
||||
flog('默认: hairline=chang_bolang, push=0.8, blend=two_stage, cm_strength=0.4;需 ComfyUI(:8188) 在跑;重绘需 local_test(:8899) 在跑', 'info');
|
||||
flog('接口12 重绘测试页加载完成(后端产出 final+纯红遮罩 → 后端 /api/v1/redraw 重绘)', 'info');
|
||||
flog('默认: hairline=chang_bolang, push=0.8, blend=two_stage, cm_strength=0.4;需 ComfyUI(:8188) 在跑', 'info');
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user