Files
2026-10-08 09:46:47 +08:00

268 lines
11 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>BiRefNet WebUI · 智能抠图</title>
<link rel="icon" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'%3E%3Crect width='32' height='32' rx='8' fill='%234f8cff'/%3E%3Cpath d='M9 21c4-1 5-10 14-10-4 1-5 10-14 10z' fill='white'/%3E%3C/svg%3E">
<link rel="stylesheet" href="/static/style.css">
</head>
<body>
<header class="topbar">
<div class="brand">
<span class="logo" aria-hidden="true">
<svg viewBox="0 0 32 32" width="26" height="26"><rect width="32" height="32" rx="8" fill="var(--accent)"/><path d="M9 21c4-1 5-10 14-10-4 1-5 10-14 10z" fill="#fff"/></svg>
</span>
<h1>BiRefNet <em>WebUI</em></h1>
</div>
<dl class="meta" id="meta">
<div><dt>设备</dt><dd id="meta-device">检测中…</dd></div>
<div><dt>模型</dt><dd id="meta-models">—</dd></div>
<div><dt>模型代码</dt><dd id="meta-node" class="path" title="">—</dd></div>
</dl>
<div class="topbar-actions">
<button class="btn ghost sm" id="btn-reload-models" type="button">重新扫描模型</button>
<button class="btn ghost sm" id="btn-unload" type="button">卸载显存</button>
</div>
</header>
<main class="layout">
<!-- ============================= 参数面板 ============================= -->
<aside class="sidebar">
<section class="block">
<header class="block-head"><h2>1 · 图片</h2><span class="hint" id="file-count">未选择</span></header>
<div class="dropzone compact" id="dropzone" tabindex="0" role="button" aria-label="选择或拖入图片">
<p>拖入图片 / 点击选择 / <kbd>Ctrl</kbd>+<kbd>V</kbd> 粘贴</p>
<p class="sub">支持 PNG · JPG · WebP · BMP · TIFF · 一次一张,新图会替换上一张</p>
<input type="file" id="file-input" accept="image/*" hidden>
</div>
<ul class="thumbs" id="thumbs"></ul>
<p class="pending-note" id="pending-note"></p>
</section>
<section class="block">
<header class="block-head"><h2>2 · 模型</h2><span class="hint" id="model-hint"></span></header>
<label class="field">
<span>权重文件</span>
<select id="opt-model"></select>
</label>
<div class="field-row">
<label class="field">
<span>设备</span>
<select id="opt-device">
<option value="auto">自动 (GPU)</option>
<option value="cpu">CPU</option>
</select>
</label>
<label class="field">
<span>精度</span>
<select id="opt-dtype">
<option value="auto">自动 (fp16 加速)</option>
<option value="float32">float32 · 最稳</option>
<option value="float16">float16 · 最省显存</option>
<option value="bfloat16">bfloat16</option>
</select>
</label>
</div>
<label class="field">
<span>架构</span>
<select id="opt-arch">
<option value="auto">自动识别</option>
<option value="v1">v1(新版,safetensors)</option>
<option value="old">old(旧版 .pth)</option>
</select>
</label>
</section>
<section class="block">
<header class="block-head"><h2>3 · 参数</h2><span class="hint">按需调整</span></header>
<label class="field">
<span>预处理尺寸</span>
<select id="opt-resolution-mode">
<option value="square">固定 1024×1024(推荐)</option>
<option value="longest">长边自适应(保宽高比)</option>
<option value="custom">自定义宽高</option>
</select>
</label>
<div class="field-row" id="row-longest">
<label class="field">
<span>长边像素</span>
<input type="number" id="opt-longest-side" value="1024" min="32" max="4096" step="32">
</label>
</div>
<div class="field-row hidden" id="row-wh">
<label class="field">
<span>宽</span>
<input type="number" id="opt-width" value="1024" min="32" max="4096" step="32">
</label>
<label class="field">
<span>高</span>
<input type="number" id="opt-height" value="1024" min="32" max="4096" step="32">
</label>
</div>
<div class="field-row">
<label class="field">
<span>插值方式</span>
<select id="opt-upscale">
<option value="bilinear">bilinear</option>
<option value="bicubic">bicubic</option>
<option value="nearest">nearest</option>
<option value="nearest-exact">nearest-exact</option>
</select>
</label>
<label class="field">
<span>遮罩阈值</span>
<input type="number" id="opt-threshold" value="0" min="0" max="1" step="0.004">
</label>
</div>
<label class="field">
<span>背景</span>
<select id="opt-background">
<option value="transparent">透明(PNG Alpha)</option>
<option value="color">纯色背景</option>
</select>
</label>
<div class="field-row hidden" id="row-bgcolor">
<label class="field">
<span>背景色</span>
<input type="color" id="opt-bgcolor" value="#ffffff">
</label>
<div class="swatches" id="swatches">
<button type="button" data-color="#ffffff" style="--c:#ffffff" title="白"></button>
<button type="button" data-color="#000000" style="--c:#000000" title="黑"></button>
<button type="button" data-color="#00ff00" style="--c:#00ff00" title="绿幕"></button>
<button type="button" data-color="#4f8cff" style="--c:#4f8cff" title="蓝"></button>
</div>
</div>
<label class="check">
<input type="checkbox" id="opt-refine" checked>
<span>前景精修(去除边缘残留背景色)</span>
</label>
<div class="field-row" id="row-blur">
<label class="field">
<span>大核 r1</span>
<input type="number" id="opt-blur1" value="90" min="1" max="255">
</label>
<label class="field">
<span>小核 r2</span>
<input type="number" id="opt-blur2" value="6" min="1" max="255">
</label>
</div>
<label class="check">
<input type="checkbox" id="opt-mask">
<span>同时输出遮罩(灰度 PNG)</span>
</label>
<label class="field">
<span>最终尺寸 · 最长边(0 = 保持原图尺寸)</span>
<input type="number" id="opt-final-side" value="0" min="0" max="32768" step="16">
</label>
<p class="field-tip">非 0 时按原图比例等比缩放,使结果最长边等于该值。例:2000×3000 填 1440 → 960×1440</p>
</section>
<section class="block actions">
<button class="btn primary" id="btn-run" type="button" disabled>开始抠图</button>
<div class="progress" id="progress" hidden>
<div class="bar"><i id="progress-bar"></i></div>
<div class="progress-meta">
<span id="progress-stage">等待中</span>
<button class="btn link" id="btn-cancel" type="button">取消</button>
</div>
</div>
<p class="error-text" id="error-text" hidden></p>
</section>
<section class="block">
<header class="block-head"><h2>4 · 批量处理</h2><span class="hint">按目录批量抠图</span></header>
<label class="field">
<span>图片目录(模板路径)</span>
<input type="text" id="batch-input-dir" placeholder="例:F:\photos\待抠图" spellcheck="false" autocomplete="off">
</label>
<label class="field">
<span>输出目录</span>
<input type="text" id="batch-output-dir" placeholder="默认:项目 outputs 目录" spellcheck="false" autocomplete="off">
</label>
<label class="check">
<input type="checkbox" id="batch-recursive">
<span>包含子目录</span>
</label>
<button class="btn" id="btn-batch" type="button">开始批量抠图</button>
<div class="progress" id="batch-progress" hidden>
<div class="bar"><i id="batch-progress-bar"></i></div>
<div class="progress-meta">
<span id="batch-progress-stage">准备中…</span>
<button class="btn link" id="btn-batch-cancel" type="button">取消</button>
</div>
</div>
<p class="error-text" id="batch-error" hidden></p>
<p class="batch-note">
两个目录都必须<strong>已存在</strong>(本工具不会自动创建,路径不对会直接报错)。结果写入输出目录,命名
<code>RMBG_原名_时间戳.后缀</code>,原名超 20 字符截断;抠图参数沿用左侧当前设置。
</p>
</section>
</aside>
<!-- ============================= 结果区 ============================= -->
<section class="stage">
<header class="stage-head">
<h2>结果 <span class="count" id="result-count">0</span></h2>
<div class="stage-tools">
<div class="segmented" id="view-switch">
<button type="button" data-view="cutout" class="active">抠图</button>
<button type="button" data-view="mask">遮罩</button>
<button type="button" data-view="original">原图</button>
</div>
<button class="btn ghost sm" id="btn-zip" type="button" disabled>打包下载 ZIP</button>
<button class="btn ghost sm" id="btn-clear" type="button" title="清空整个结果列表" disabled>清空</button>
</div>
</header>
<p class="stage-tip">结果会一直保留在列表里(传新图、改参数都不会清空)· 点文件名或「重新处理」会套用它上次使用的参数 · 点卡片选中 · 点 × 移除单条</p>
<section class="batch-report" id="batch-report" hidden>
<header class="batch-report-head">
<h3>批量任务 <span class="badge" id="batch-badge">排队中</span></h3>
<span class="batch-report-path" id="batch-report-path" title=""></span>
<button class="btn ghost sm" id="btn-batch-hide" type="button">收起</button>
</header>
<p class="batch-report-sum" id="batch-report-sum"></p>
<ul class="batch-rows" id="batch-rows"></ul>
</section>
<div class="empty-state" id="empty">
<div class="empty-art" aria-hidden="true">
<svg viewBox="0 0 240 140" width="240" height="140">
<rect x="1" y="1" width="238" height="138" rx="14" fill="none" stroke="var(--border)" stroke-dasharray="6 6"/>
<circle cx="70" cy="62" r="22" fill="none" stroke="var(--accent)" stroke-width="2"/>
<path d="M104 92c14-4 18-40 52-40-14 4-18 40-52 40z" fill="var(--accent)" opacity=".85"/>
<path d="M46 108h148" stroke="var(--border)" stroke-width="2" stroke-linecap="round"/>
</svg>
</div>
<h3>还没有结果</h3>
<p>左侧拖入图片 → 选择模型 → 点击「开始抠图」。处理完成后可拖拽分割线对比原图与抠图效果,记录会累积在右侧供随时重新处理。</p>
</div>
<div class="grid" id="results"></div>
</section>
</main>
<script src="/static/zip.js"></script>
<script src="/static/app.js"></script>
</body>
</html>