Releases: storyAura/BooruDatasetTagManagerPlus
Release list
v1.2.5
BooruDatasetTagManager+ v1.2.5(中文)
新功能
- 批量裁剪:同一分辨率的图片共用一个裁剪框;自由框选,或锁定 1:1、2:3、16:9 等比例 / 自定义长宽比;可覆盖原图或另存
_crop。 - 多重切割:来源为选中 / 当前文件夹 / 全部;模式包括仅压缩、居中裁切、切片分割、随机位置切割、YOLO 检测切图;按长边档位另存新文件,不覆盖原图。
- YOLO 检测:独立窗口画检测框、勾选保留,可选 ONNX 反推标签后再导出切图。模型下拉含 deepghs 动漫全身 / 脸 / 头(默认全身 small),也可导入自定义 YOLOv8 ONNX。
- 标签一二级筛选:内置约 10 万条 Danbooru 通用标签目录。左侧勾选一级,悬停后右侧列出二级;可多选、可搜索。角色名仍靠 Danbooru 类型 / 角色表。
- 按标签分类到文件夹:勾选若干标签后,同时带齐这些标签的图片移入一个新文件夹;可命名,留空则为
Mix,重名自动Mix_2/Mix_3。 - 预分桶:按分辨率分桶,给图片加白边扩到固定尺寸后写入当前数据集下的
{宽}x{高}文件夹;默认不放大,可合并到 4 / 8 / 12 / 16 个桶,并估算训练步数。写完删除已分出的原图和已空的原文件夹。 - 数据集文件夹组头支持 F2 / 双击 改名。
settings.json(含 LLM/API 配置)改存「文档\BooruDatasetTagManagerPlus」,换安装目录读同一份。
修复
- ONNX 推标下载完成后,文件被占用或环境缺运行库时不再把模型当损坏删掉。
- 翻译标签:词表 / 缓存命中立刻写入译文列;中文界面下错误的默认「俄语」改回简体中文,避免整表卡住。
- 批量裁剪「应用到全部」不再因预览图已释放报错。
- 按标签分类勾选标签时不再崩溃。
批量裁剪
- 入口:数据集右键「批量裁剪…」,或 工具 → 批量裁剪…。
- 同一分辨率才一起裁:以当前参考图的像素大小为准;分辨率不同的图片和视频会跳过。只选了一张时,默认包含当前视图中所有相同分辨率的图片。
- 交互:在参考图上拖出选区;可拖动、拖角/边调整。长宽比可选自由、原版、自定义,以及 1:1 / 1:2 / 2:1 / 2:3 / 3:2 / 3:4 / 4:3 / 16:9 / 9:16。位置与宽高也可直接填数字。
- 写出:覆盖原图(先确认)或另存
_crop副本(标签文件一并复制并导入数据集)。
多重切割工具
- 入口:数据集右键「多重切割…」、文件夹组头「多重切割此文件夹 / 全部」,或 工具 → 多重切割…。来源为选中 / 当前文件夹 / 全部。始终另存新文件,原图保留;标签文件一并复制并导入数据集。
- 五种模式:仅等比例压缩把长边压到勾选档位;居中裁切到比例先取图内最大居中矩形再压缩;切片分割到比例在原图上铺档位大小的窗口;随机位置切割每张切 N 块(默认 1);YOLO 检测以检测框中心扩成选定比例再压档,未检出则跳过。
- YOLO:下拉可选 deepghs 动漫全身 / 脸 / 头多档(默认全身
person_detect_v1.1_s),也可导入自定义 YOLOv8 ONNX。下载源与 ONNX 推标共用。 - 档位:默认 512 / 768 / 896 / 1024 / 1280 / 1536,可多选或自定义。已经小于该档的图会跳过,不放大。
YOLO 检测
- 入口:多重切割选「YOLO 检测」,或 工具 → YOLO 检测…。
- 模型:全身 / 脸 / 头(默认全身 small)。脸/头模型裁的是脸或头,适合特写。未下载时点「下载模型」,或直接检测时自动下载。
标签类别一二级筛选
- 数据:约 10 万条 Danbooru 通用标签,带一二级分类。通用标签先查这份表;查不到进「一般」。角色名仍靠 Danbooru 类型 / 角色表。
- 界面:两个标签面板均为左右两栏。勾一级即筛整个大类;悬停后右侧列出二级。可多选、可搜索。
预分桶
- 入口:数据集右键「预分桶…」、文件夹组头「预分桶此文件夹 / 全部」,或 工具 → 预分桶…。写出到当前数据集下的
{宽}x{高}文件夹。标签文件一并复制;写完后删除已分出的原图和已空的原文件夹。 - 分桶设置:分辨率(默认 1536×1536)、最小 / 最大边、划分单位(通常 64)。「不放大(只加白边)」默认开启。
- 目标桶数:全部 = 按宽高比各成一桶;填 N 或点 4 / 8 / 12 / 16 则把相近比例合并到 N 个文件夹。
- 步数估算:按重复 / 批次 / Epochs 估算理论步数和分桶后的实际步数。
按标签分类到文件夹
- 入口:工具 → 按标签分类到文件夹…。勾选标签后移动同时带齐这些标签的图片与标签文件。
- 文件夹名:可填写;留空则为
Mix。已有同名文件夹时自动变成Mix_2、Mix_3。 - 改名:新文件夹出现后,组头 F2 或 双击 即可改成 kohya 风格名称。
配置路径
- 整份
settings.json(界面偏好 + LLM/API 配置)写到「文档\BooruDatasetTagManagerPlus」。设置 → 常规 显示实际路径。 - 文档目录还没有文件时,从程序目录复制一次。文档里已是空配置、但程序目录仍有旧 API 时,只把 API 字段迁过去。本机换安装目录会读同一份;换电脑仍需重填密钥。
BooruDatasetTagManager+ v1.2.5 (English)
New
- Batch crop: one crop rectangle shared across every image of the same resolution; free selection or locked ratios (1:1, 2:3, 16:9, …) / custom aspect; overwrite or save
_cropcopies. - Multi-crop: source is selected / current folder / all images; modes are scale-only, center-crop, tile-split, random-position crop, and YOLO detect crop; writes new files at long-edge gears and never overwrites originals.
- YOLO detect: standalone window to draw boxes, keep or drop them, optionally ONNX-tag kept crops, then export. Dropdown covers deepghs anime person / face / head (default full-body small), plus custom YOLOv8 ONNX import.
- Two-level category filter: bundled ~100k danbooru general-tag catalog. Tick a primary on the left, hover to list secondaries on the right; multi-select and searchable. Character names still use Danbooru type / the character table.
- Classify into folders by tag: tick tags, then images that have every selected tag move into one folder; type a name or leave it blank for
Mix. A name that already exists becomesMix_2/Mix_3. - Pre-bucket: letterbox each image onto a fixed bucket size and write
{width}x{height}folders under the current dataset; pad-only by default; merge down to 4 / 8 / 12 / 16 buckets and estimate training steps. After writing, source images and emptied source folders are removed. - Dataset folder headers can be renamed with F2 or a double-click.
settings.json(including LLM/API profiles) now lives inDocuments\BooruDatasetTagManagerPlus, so install folders share one file.
Fixed
- ONNX tagger downloads no longer delete a model that is still locked or fails to load because a native runtime is missing.
- Tag translation: built-in dictionary / cache hits appear immediately. A leftover default translation target of Russian on a Chinese UI is remapped to Simplified Chinese so the column no longer hangs empty.
- Batch-crop Apply-all no longer errors when the preview image has already been released.
- Classify-into-folders no longer crashes when ticking tags.
Batch crop
- Entry: dataset context menu Batch crop…, or Tools → Batch crop….
- Same resolution only: the reference image's pixel size is the key; different sizes and videos are skipped. With a single selection, every image of that size in the current view is included by default.
- Interaction: drag a rectangle on the reference; move it or resize from corners/edges. Aspect can be free, original, custom, or 1:1 / 1:2 / 2:1 / 2:3 / 3:2 / 3:4 / 4:3 / 16:9 / 9:16. Position and size can also be typed.
- Write: overwrite in place (confirm first) or save
_cropcopies (tag files are cloned and imported).
Multi-crop tool
- Entry: dataset context menu Multi-crop…, folder-header Multi-crop this folder / all images, or Tools → Multi-crop…. Source is selected / current folder / all. Always writes new files (originals stay); caption files are cloned and imported.
- Five modes: Scale only shrinks the long edge to each ticked gear; Center-crop to ratio takes the largest centered rectangle then downscales; Split into tiles lays gear-sized windows on the source; Random-position crop takes N crops per image (default 1); YOLO detect expands each detection to the chosen ratio then applies gears, skipping images with no hit.
- YOLO: dropdown covers deepghs anime person / face / head (default full-body
person_detect_v1.1_s), plus custom YOLOv8 ONNX import. Download source is shared with the ONNX tagger. - Gears: defaults 512 / 768 / 896 / 1024 / 1280 / 1536, multi-select or custom. Images already smaller than a gear are skipped; never upscales.
YOLO detect
- Entry: Multi-crop's YOLO detect mode, or Tools → YOLO detect….
- Models: person / face / head (default full-body small). Face/head models crop the face or head — better for close-ups. If the file is missing, Download model fetches it, or Detect downloads automatically.
Two-level tag category filter
- Data: ~100k danbooru general tags with L1/L2 categories. General tags look up this table first; unknown tags land in General. Character names still use Danbooru type / the character table.
- UI: both tag panes use a two-column picker. Tick a primary to filter that whole group; hover lists secondaries on the right. Multi-select and searchable.
Pre-bucket
- Entry: dataset context menu Pre-bucket…, folder-header Pre-bucket this folder / all images, or Tools → Pre-bucket…. Writes
{width}x{height}folders under the current dataset. Captions are cloned. After writing, source images and emptied source folders are removed. - Bucket settings: resolution (default 1536×1536), min / max side, step (usually 64). Do not upscale (pad only) is on by default.
- Target count: All keeps every aspect-assigned bucket; type N or tap 4 / 8 / 12 / 16 to merge neighboring ratios down to N folders.
- Step estimate: repeats / batch / epochs produce a theoretical count and the actual count after bucketing.
Classify into folders by tag
- Entry: Tools → Classify into folders by tag…. Tick tags, then move images that have every selected tag, along with their caption files.
- Folder name: type one, or leave it blank for
Mix. A name that already exists becomesMix_2, thenMix_3. - Rename: after the folders appear, F2 or double-click a group header to give it a kohya-style name.
Settings path
- The whole
settings.json(UI preferences + LLM/API profiles) is written toDocuments\BooruDatasetTagManagerPlus. Settings → General shows the actual path. - If Documents has no file yet, the exe-adjacent file is copied once. If Documents already exists without API config but the old file still has one, only those API fields are merged in. Switching install folders on the same Windows user reuses the same file; a different PC still needs keys re-entered.
v1.2.4
BooruDatasetTagManager+ v1.2.4(中文)
针对性修复:多人角色审查结果页角色下拉同步、WD14 错色标签、超长文件名原子保存失败、LLM 大批量打标二次确认;错误标签修复的子级并入改为默认关闭并可逐条勾选;ONNX 推标按置信度排序;文件名以 _ 结尾时打标不再报错;视频抽帧新增按百分比随机抽取;数据集可按类型排序。
多人角色审查
- 「应用并保存」后左上角角色下拉会跟进到下一个角色:多人模式下中间角色的「应用并保存」本来就会切到下一角色的审查表与参考图,但下拉框仍停在上一角色(例如仍显示角色A)。现
SwitchResultProfile会同步comboResultProfile.SelectedIndex。
WD14 ONNX 推标
- 修复通道顺序导致的错色标签:GDI
Format24bppRgb内存已是 BGR,预处理器却再做了一次 R↔B,实际喂给模型的是 RGB,容易把发色等标签推错(例如绿发出现blue hair)。现按 CL v1 约定直接按 BGR 打包 NHWC;alpha 仍先合成到白底,不会向模型送 RGBA。 - 按置信度排序,不再按 CSV 字母序:
selected_tags.csv的 general/character 行本身是 A–Z,SortMode.None以前原样写出,看起来像「打标自动按首字母排序」。现 WD14 / PixAI / CL 在返回前按置信度降序(与官方 wd14-tagger 一致);新用户默认排序为置信度。Alphabetical仍可强制 A–Z。LLM 打标不改模型自己的顺序。
超长文件名保存
- 原子写临时名不再接到目标文件名后面:danbooru 式超长图片名(逗号分隔标签作文件名)本身合法,但
SafeFile/ 角色审查事务在旁边生成原名.{guid}.tmp时会把 Windows 单段文件名撑过 255 字符,报「文件名、目录名或卷标语法不正确」。现改为同目录短名.bdtm-{guid}.tmp,主窗口保存与审查「应用并保存」均受益。 - 文件名以
_结尾可以打标/写 caption:foo_.png会配对foo_.txt;LLM 请求按扩展名给出正确 MIME(含.jpeg),不再把foo_.jpeg当成application/octet-stream被接口拒绝。
LLM 打标
- 超过 200 张时二次确认:解析输入列表后、开始任务前弹出 Yes/No,提示张数与可能的 API 费用,避免误选整库后误点开始。ONNX 推标本地免费,不加此门闩;CLI 不变。
错误标签修复
- 子级并入父级默认关闭:服装差分(如
kayoko (dress) (blue archive))不再因为数据集出现量 < 30 就自动并入父级。测试模块改为可勾选,勾选后仍用数据集出现量(不是 CSV 的post_count)与默认阈值 30。CLI--child-threshold默认改为 0。 - 预览表可逐条勾选:默认全选,可全选/全不选,确定后只应用勾中的行。
视频抽帧
- 按百分比随机抽帧:抽帧页新增「随机抽帧」,滑条 1–100%(默认 10%)。分布抽帧把视频均分成 N 段、每段随机取一帧;区域抽帧随机取一段连续的 N 帧。百分比与模式会记住。指定帧 / 随机抽帧的状态显示「当前/总数」和源帧号,不再跟着 ffmpeg 单帧任务的
frame=0/frame=1闪烁。勾选删除源视频后抽帧窗口自动关闭。
数据集浏览
- 可按类型排序:搜索框右侧新增排序按钮。类型按扩展名分组(jpg 与 jpeg 算一类;png、webp、gif 等图片,以及 mp4、webm、mkv 等视频,各自一类),同类内仍按文件名。也可切回文件名或图片/标签修改时间;选择写入设置,下次打开仍在。
其他
- 测试套件从 564 增长到 611(WD14 通道打包、超长文件名原子写、审查事务长名写入、子级并入默认关、ONNX 置信度排序、
_结尾文件名、随机抽帧规划、抽帧进度、按类型排序)。
BooruDatasetTagManager+ v1.2.4 (English)
Targeted fixes: multi-character audit profile dropdown sync, WD14 wrong-color tags, atomic-save failures on very long filenames, a confirmation before large LLM tagging batches, rare-child fold off by default with per-row preview checks, ONNX confidence sort, tagging files whose names end with _, random percentage frame extraction, and dataset sort by file type.
Multi-character tag audit
- Profile dropdown advances with Apply: in multi-character review, Apply on a non-final profile already switched the grid and reference preview to the next character, but the top-left dropdown stayed on the previous one (e.g. still showed Character A).
SwitchResultProfilenow syncscomboResultProfile.SelectedIndex.
WD14 ONNX tagging
- Fixes channel-order wrong-color tags: GDI
Format24bppRgbmemory is already BGR; the preprocessor swapped R↔B again and fed RGB into a BGR model, scrambling hue tags (e.g. green hair yieldingblue hair). Packing now follows the CL v1 convention (BGR NHWC as-is). Alpha is still composited onto white; the model is not given RGBA. - Sorts by confidence, not CSV alphabetical order: general/character rows in
selected_tags.csvare already A–Z, soSortMode.Noneused to write tags in that order. WD14 / PixAI / CL now return confidence-descending order (matching the official wd14-tagger); new installs default the sort combo to Confidence.Alphabeticalstill forces A–Z. LLM tagging keeps the model's own order.
Long-filename saves
- Atomic temps use short sibling names: danbooru-style long basenames (comma-separated tags as the filename) are legal, but
SafeFile/ the character-audit transaction appending.{guid}.tmpto that basename pushed the Windows path component past 255 characters (ERROR_INVALID_NAME). Temps are now short same-directory names.bdtm-{guid}.tmp, covering both main-window Save All and audit Apply. - Filenames ending with
_can be tagged:foo_.pngpairs withfoo_.txt; LLM requests send the correct MIME from the extension (including.jpeg) sofoo_.jpegis no longer rejected asapplication/octet-stream.
LLM tagging
- Confirm when more than 200 images are selected: after resolving the input list and before starting the job, a Yes/No dialog shows the count and warns about API cost. Local ONNX tagging is unchanged; the CLI is unchanged.
Tag consistency fixer
- Rare-child fold is off by default: costume variants such as
kayoko (dress) (blue archive)are no longer folded into the parent just because they appear fewer than 30 times. The Test module now has an opt-in checkbox; when checked, dataset occurrence counts (not CSVpost_count) and the existing threshold of 30 apply. CLI--child-thresholdnow defaults to 0. - Preview rows are checkable: all checked by default, with Select all / Select none; OK applies only the ticked rows.
Video frame extraction
- Random percentage sampling: the extract page now has Random (percentage), a 1–100% slider (default 10%). Distributed takes one random frame from each equal slice of the clip; Regional takes a random contiguous block of that many frames. Percent and mode are remembered. Specific and random extract status now shows current/total plus the source frame number, instead of flickering through ffmpeg's per-call
frame=0/frame=1. Choosing to delete the source videos closes the extract window.
Dataset browser
- Sort by type: a sort button next to the search box groups by extension (jpg and jpeg together; image types such as png, webp, gif and video types such as mp4, webm, mkv each their own group), then by name within the group. Name and image/tag dates remain available; the choice is saved and restored on the next launch.
Other
- The test suite grows from 564 to 611 (WD14 channel packing, long-name SafeFile writes, long-name audit transaction commits, rare-child fold default-off, ONNX confidence sort, trailing-
_filenames, random-frame planning, extract progress, file-type sort).
v1.2.3
BooruDatasetTagManager+ v1.2.3(中文)
安全 / I/O 加固与标签筛选模式修复:对照内部审计修复密钥落盘、路径穿越、下载竞态、GDI 泄漏等问题;并修正「点 NOT 得 OR」的筛选模式按钮,换标签立即重筛、再点当前模式取消筛选。新增工具「扫描坏图」,修复「替换透明背景」对 WebP 报内存溢出,并新增按当前文件夹 / 全部图片的批量替换。
替换透明背景
- 修复 WebP 报「Out of Memory」:旧实现用 GDI+ 的
Bitmap.FromFile()解码、Bitmap.Save(path, RawFormat)编码,二者都不支持 WebP——解码直接抛OutOfMemoryException(GDI+ 对无法识别的格式就报这个),即使侥幸载入也写不回 WebP。现改用与 ONNX 推标 / 图片编辑器同一条链路:ImageLoader.GetImageFromFile()(ImageSharp 解码,顺带按 EXIF 方向摆正)+ImageEditorSaveService.Encode()按目标扩展名编码,WebP / TIFF / GIF 等格式都能正常读写。 - 新增批量入口(文件夹右键菜单):在数据集浏览器的文件夹组头上右键 → 替换透明背景(当前文件夹) 处理右键点中的文件夹(Ctrl / Shift 多选时为这几个文件夹的并集),替换透明背景(全部图片) 处理整个数据集;在置顶的「全部」行上右键时前者不可用。工具 → 替换透明背景 仍只处理选中图片。三者共用同一实现,颜色对话框(纯色 / 随机色 / 随机取自颜色列表)行为一致。
- 先扫描再替换:运行前先过一遍——按扩展名只保留能带 alpha 的格式(PNG / WebP / GIF),再逐张解码检查是否真的存在透明像素(发现第一个非全不透明像素即停);只有确实带透明底的图片才会被改写。JPG / BMP 等无 alpha 格式、以及有 alpha 通道但整张不透明的 PNG / WebP 都会跳过,不会被无意义地重新编码。扫描过程状态栏显示「正在检查透明背景 (x/y)」,确认框会写明「将替换 N 张(已检查 M 张)」,全部不透明时直接提示并结束。
- 完成后状态栏汇总「已替换 N 张,跳过 M 张」,避免一堆不透明图片时看起来像什么都没发生。
- 视频文件自动跳过;写盘走
SafeFile的「写临时文件 + 原子替换」,中途失败不会毁掉原图;替换后清掉预览缓存并重建缩略图,侧栏预览不再显示旧图。 - 单张图片失败只记录到错误汇总(最多列出 20 条),不会中断整批。
扫描坏图
- 入口:工具 → 扫描坏图…。在当前数据集(含文件夹范围)内逐张用 ImageSharp 尝试解码,找出缺失 / 空文件 / 无法解码 / 尺寸无效的图片。
- 审查墙与相似图片同款交互:绿框 = 保留,红框 = 删除,左键切换;默认全部标红;可一键全标红 / 全标绿;坏图用占位 X 图,不依赖已损坏的缩略图。
- 删除标红图片走与主界面相同的事务化删除(图片与标签文件一起),完成后自动重新扫描。
标签筛选模式
- 不再「点 NOT 得 OR」:旧的模式按钮点击时先切到下一个模式再筛选,而图标显示的是当前模式——图标是 NOT 时点它,实际按 OR(含该标签)筛选,反选看起来时灵时不灵。现改为下拉菜单明选(交集 AND / 并集 OR / 反选 NOT / 异或 XOR,当前模式打勾),点哪个用哪个;未选标签就点筛选会在状态栏提示,未加载数据集时也不再空引用崩溃。
- 换标签立刻重筛:数据集筛选已开启时,在「全部标签」中点选其它标签会立即按当前模式重新筛选,无需再点一次筛选按钮。
- 再点当前模式取消:筛选开启时再次点击当前已选中的模式(例如 NOT 下再点 NOT)会退出数据集筛选。
安全 / I/O 加固
- DPAPI 加密失败时中止保存,不再把 API 密钥以明文写入
settings.json。 - LLM 打标路径正确释放 WebP / 视频帧
Image,避免批量打标 GDI 泄漏。 - 文件夹重命名拒绝
..路径穿越,并校验落在数据集根内。 - Hugging Face 模型下载按路径加锁,避免并发写坏
.partial。 - 更新包资产文件名经消毒后再落盘。
- 角色标签审查删除门控改用本地语义分类,模型无法把受保护标签误标为可删。
- Caption 输出路径强制落在输出根内。
- ffmpeg 日志捕获设上限(64 KB)。
- 主题与 TagsDB 缓存改用
SafeFile原子写。
其他
- 测试套件从 530 增长到 564(新增安全 / I/O 审计回归、坏图扫描与透明底预扫描单元测试)。
BooruDatasetTagManager+ v1.2.3 (English)
A security / I/O hardening patch plus a tag-filter mode fix: internal-audit fixes for secret persistence, path traversal, download races, and GDI leaks; the "click NOT, get OR" filter-mode bug; and live re-filter on tag change / toggle-off by re-clicking the active mode. Also adds Tools → Scan corrupted images, fixes the out-of-memory failure when replacing a transparent background on WebP files, and adds current-folder / whole-dataset batch runs.
Transparent background replacement
- Fixes "Out of Memory" on WebP: the old code decoded with the GDI+
Bitmap.FromFile()and encoded withBitmap.Save(path, RawFormat), neither of which supports WebP — decoding threwOutOfMemoryException(what GDI+ reports for formats it cannot parse) and even a successful load could not be written back as WebP. It now uses the same path as the ONNX tagger and the image editor:ImageLoader.GetImageFromFile()(ImageSharp decode, EXIF orientation applied) plusImageEditorSaveService.Encode()keyed on the target extension, so WebP / TIFF / GIF round-trip correctly. - New batch entries (folder context menu): right-click a folder group header in the dataset browser → Replace transparent background (current folder) processes the folder you clicked (the union of the folders, when several are Ctrl/Shift-selected), and Replace transparent background (all images) processes the whole dataset; on the pinned "All" row the folder variant is disabled. Tools → Replace transparent background still applies to the selection only. All three share one implementation, so the color dialog (solid / random / random-from-list) behaves identically.
- Scans before it writes: a pre-pass keeps only alpha-capable formats (PNG / WebP / GIF) by extension, then decodes each one to check whether it really has transparent pixels (stopping at the first non-opaque pixel). Only files with an actual transparent background are rewritten — alpha-less formats (JPG, BMP, …) and fully opaque PNG / WebP files are skipped instead of being pointlessly re-encoded. The status bar shows "Checking for transparent backgrounds (x/y)", the confirmation states how many will be replaced out of how many were checked, and an all-opaque scope simply reports that and stops.
- On completion the status bar summarizes "N replaced, M skipped", so a folder of opaque images does not look like nothing happened.
- Videos are skipped; writes go through
SafeFile(temp file + atomic replace), so a mid-write failure cannot destroy the original. After each replacement the preview cache is dropped and the thumbnail rebuilt, so the sidebar no longer shows the old image. - A failure on one image is collected into an error summary (first 20 listed) instead of aborting the batch.
Corrupted image scanner
- Entry: Tools → Scan corrupted images…. Walks the loaded dataset (honoring folder scope) and tries ImageSharp decode on each file — reports missing / empty / undecodable / invalid-size images.
- Review wall matches the similar-image finder: green = keep, red = delete, left-click toggles; defaults to all marked for delete; bulk mark-all keep/delete; broken files use an X placeholder instead of a dataset thumbnail.
- Delete red-marked images uses the same transactional delete as the main window (image + caption), then rescans.
Tag filter mode
- No longer applies OR when the icon says NOT: the old mode button cycled to the NEXT mode on click while its icon showed the CURRENT one — clicking the NOT icon actually applied an OR filter (images WITH the tag), so inverse filtering seemed to fail at random. It is now a dropdown listing the four modes (AND / OR / NOT / XOR, active one checked): the mode you pick is the mode applied. Filtering with no tag selected now shows a status hint, and with no dataset loaded it no longer crashes with a null reference.
- Re-filters immediately when you pick another tag: with a dataset tag-filter already active, selecting a different All Tags row re-applies the current mode right away — no second click on the filter button.
- Re-clicking the active mode cancels: while a filter is on, choosing the already-selected mode again (e.g. NOT while already on NOT) exits the dataset filter.
Security / I/O hardening
- DPAPI encrypt failure aborts the settings save — API keys are no longer written as plaintext.
- LLM tagging disposes WebP / video-frame
Imageinstances (fixes a batch GDI leak). - Folder rename rejects
..traversal and keeps paths under the dataset root. - Hugging Face model downloads are serialized per target path (no concurrent
.partialcorruption). - Update zip asset filenames are sanitized before download.
- Character tag audit delete gating uses the local semantic classifier so the model cannot mislabel protected tags as deletable.
- Caption output paths are contained under the output root.
- ffmpeg captured logs are capped (64 KB).
- Color scheme and TagsDB cache writes use atomic
SafeFile.
Other
- The test suite grows from 530 to 564 (new security / I/O audit regressions, corrupted-image scanner and transparent-background pre-scan unit tests).
v1.2.1
BooruDatasetTagManager+ v1.2.1(中文)
由第二轮全库审计驱动的加固与清理版本:ONNX、网络与图片管线的内存与数据安全修复,legacy Python 后端彻底移除,数据集浏览器更聪明的范围筛选(根目录组、多文件夹并集),以及绝不丢弃已付费结果的双角色审查断点机制。
移除 legacy Python 后端
- 外置 Python
AiApiServer/后端整体删除,连同其客户端(AiApiClient+ DTO)、"ai-api-server" 自动打标提供方、AiApiServer 设置窗口与 moondream2 自动裁剪功能(约删除 9,600 行)。背景移除与打标早在数个版本前就已全部在客户端内完成。 - 仍选择已删除提供方的旧
settings.json会在启动时自动迁移到 OpenAI 兼容提供方——无需任何重新配置。 - 休眠已久的
WebPWrapper原生绑定(WebP 解码早已移交 ImageSharp)一并移除。
数据集浏览器:根目录筛选与多文件夹并集
- 根目录组
(root)现在拥有自己的显式范围键:点击其表头会筛选出直接位于数据集根目录下的图片,而不是默默等同于"全部"。根目录组的重命名仍然禁用。 - Ctrl/Shift 多选文件夹表头会把数据集范围切换为所选文件夹的并集——图片列表与全部标签计数实时跟随选择;全部取消选择则回落到"所有文件夹"。文件夹右键打标使用同一并集范围。
- 折叠分组(或收窄搜索过滤)会把被隐藏的图片从网格镜像两侧的选择中剪除,删除/批量操作不会再碰到浏览器已经不显示的行。
- 浏览器搜索输入加入 200ms 防抖;首次数据集加载以一次排序构建全部标签列表,取代逐标签的有序插入(此前在大标签集上是 O(n²))。
双角色审查:断点续跑
- 若角色 A 已完成而角色 B 的审查失败,A 的已付费结果会作为断点保留:向导会报告哪个角色失败、原因、已完成角色大约消耗了多少 tokens,并提供只重试失败角色的选项,不为已完成的角色重复计费。
- 两张参考图会在第一次模型调用前真正解码(损坏或标错的文件现在会在花钱之前就失败),进度行也会预先说明模型请求的最大数量。
可靠性与数据安全(审计第二批)
- ONNX 打标器(WD14 / PixAI / CL): 图片预处理不再物化巨大的 maxDim×maxDim 中间图(10,000px 的图片曾经要 ~300 MB),也不再泄漏临时位图;DirectML 会话失败先在 CPU 上重试,然后才判定文件损坏;用户取消、缺失原生运行库与缺失文件不再清空数百 MB 的模型缓存;标签 CSV 必须至少包含一行数据才算就绪;续传下载在 416 时校验服务器的
Content-Range总长;会话输出名保留模型的真实大小写;SessionOptions原生句柄会被释放。 - 网络与更新器: Danbooru wiki 预览只从
donmai.us主机经 HTTPS 下载图片并限制 5 MB;Danbooru 与 GitHub 请求在 429 时遵循Retry-After并只做一次有界重试;更新检查只接受 win-x64 zip(不再回退到任意资源),下载后校验 GitHub 的sha256摘要;指向远程主机的明文 HTTP 端点保存前需要显式确认。 - 密钥与供应链: DPAPI 加密失败会警告而不是悄悄把 API 密钥存成明文;明文→加密迁移会连续保存两次,让旧明文也从
settings.json.bak中轮换掉;打包的 ffmpeg 下载固定到特定 BtbN 构建并校验(压缩包 + 二进制大小),不再跟随滚动的latest标签。 - 图片管线: 多区域裁剪导出按扩展名用真实格式编码(含 webp/tif),原子写入、防重名、不留半批;裁剪预览不再每个区域泄漏一张全尺寸位图;图片编辑器的撤销历史改为 512 MB 字节预算上限,取代固定 15 张全图快照;EXIF 方向在加载时烘焙,相机照片不再横躺显示(与保存);moondream 时代的
Image.FromFile文件锁从剩余工具中清除。 - 文件与视频: 删除会解析图片真实的字幕扩展名(
.txt或.caption),视频与图片走同一条可回滚的分段删除路径;合法但为空的审查事务清单不再让数据集加载崩溃;ffprobe 失败会抛错而不是默默报出全零的视频信息;取消/失败的转换会清理半成品输出;抽帧导入会排除此前抽帧的残留文件。 - 翻译: 整条翻译链传递
CancellationToken,回退超时(或调用方取消)会真正取消在途 HTTP 请求,而不是任其在后台继续运行。 - 标签列表完整性: 图片标签列表内部维护着一个文本镜像,网格重绑定遗弃单元格编辑事务时它可能悄悄失步(之后的批量替换/删除报 "List desynchronization detected",失败的变更还会进一步破坏列表)。现在程序化替换/删除会先提交悬挂的编辑事务,网格重绑定前冲掉未完成编辑,检测到失步时自动修复(重建镜像并在可执行文件旁写出
ErrorData.json),不再在变更中途抛异常。
界面、无障碍、多语言
- 慢速的多选标签表构建不再覆盖其后选中图片的标签;批处理任务运行时主窗口拒绝关闭;自动打标设置探测会先停掉计时器再等待(不再堆叠探测、重复列表)。
- 悬浮预览窗从"永远置顶"改为从属窗口:仍浮在主窗口之上,但不再遮挡模态确认框(被藏住的确认框曾让整个程序看起来像卡死)。
- 标签表格加入 Tab 键顺序;视频工具窗口适配小屏(低于 1080×820 可滚动);LLM/ONNX/视频窗口支持 Esc 关闭;审查向导 DPI 感知;搜索未命中改在状态栏播报而非仅靠颜色。
- 高 DPI 下的 LLM 设置对话框: 对话框现在像应用的其他窗口一样声明 96-DPI 设计基线,API 密钥行也留出了余量——125% 显示缩放下,密钥列表下方"多个密钥轮流使用"的提示曾被拦腰截断。
- zh-TW/ru/pt-BR 中 42 条未翻译(英文占位)的文案已补齐,图片分拣窗口完成全量本地化(五种语言各新增 17 个键)。
- 程序内更新提示按界面语言显示: 从本版本起,发行说明以中英两份独立全文发布(以语言标记分隔),启动时与手动检查更新的弹窗只显示与界面语言匹配的那份;启动提示文案本身也完成本地化(此前是硬编码英文)。
- README 不再以绝对化措辞承诺"批量工具绝不破坏原文件"(视频替换原文件本来就会按设计删除源文件——现已如实说明);UI 结构文档描述了当前的浏览器/内嵌预览布局。
工程与杂项
- Debug 菜单改造为可选调试模式。 旧的开发者专用测试项(分拣设置、空图片网格窗、手动裁剪)已移除。新的调试模式开关(设置 → 常规,默认关闭)会显示 Debug 菜单,并把带时间戳的运行信息写入可执行文件旁的
debug.log——启动版本/系统信息,以及crash.log每条记录的镜像;菜单中的"打开调试日志"可直接打开该文件。 global.json固定 .NET SDK 下限(稳定版 ≥ 8.0,最新主版本);test_start.bat启动最新构建的程序而不是过期的 Release;check_update.bat返回真实退出码;publish_release.bat在把版本参数展开进路径与gh命令之前先校验它。- 测试套件从 439 增长到 481(新增回归:预览 URL 白名单、仅表头 CSV、翻译超时取消、根范围哨兵、多文件夹并集范围、双审查断点/续跑、发行说明语言分节)。
BooruDatasetTagManager+ v1.2.1 (English)
A hardening and cleanup release driven by the second wave of the full-codebase audit: memory and data-safety fixes across the ONNX, network and image pipelines, the legacy Python backend removed for good, smarter dataset-browser scoping (root group, multi-folder union), and checkpointed dual-character audits that never throw away paid results.
Legacy backend removed
- The external Python
AiApiServer/backend is deleted entirely, together with its client (AiApiClient+ DTOs), the "ai-api-server" auto-tag provider, the AiApiServer settings window and the moondream2 auto-crop feature (~9,600 lines removed). Background removal and tagging have been fully in-client for several releases. - Old
settings.jsonfiles that still select the removed provider migrate automatically to the OpenAI-compatible provider at startup — nothing to reconfigure. - The dormant
WebPWrappernative bindings (WebP decoding moved to ImageSharp long ago) are also gone.
Dataset browser: root scope and multi-folder union
- The root group
(root)now has its own explicit scope key: clicking its header filters to images directly under the dataset root, instead of silently meaning "everything". Renaming stays disabled for the root group. - Ctrl/Shift multi-selecting folder headers now scopes the dataset to the union of the selected folders — the image list and the All Tags counts follow the selection live; deselecting everything falls back to "all folders". Folder right-click tagging uses the same union scope.
- Collapsing a group (or narrowing the search filter) prunes the now-hidden images from the selection on both sides of the grid mirror, so delete/bulk actions can no longer touch rows the browser no longer shows.
- Browser search input is debounced (200 ms), and the first dataset load builds the All Tags list with a single sort instead of a per-tag sorted insert (previously O(n²) on large tag sets).
Dual-character audit: checkpoints
- If character B's audit fails after character A already completed, A's paid result is kept as a checkpoint: the wizard reports which character failed, why, and roughly how many tokens the completed characters consumed, then offers to retry only the failed character without re-billing the finished one.
- Both reference images are actually decoded before the first model call (a corrupt or mislabeled file now fails before any money is spent), and the progress line states the maximum number of model requests up front.
Reliability & data safety (audit wave 2)
- ONNX taggers (WD14 / PixAI / CL): the image preprocessor no longer materializes a giant
maxDim×maxDimintermediate (a 10,000 px image used to cost ~300 MB) and no longer leaks temporary bitmaps; DirectML session failures retry on CPU before anything is declared corrupt; user cancels, missing native runtimes and missing files no longer purge a multi-hundred-MB model cache; a labels CSV must contain at least one data row to count as ready; resumed downloads validate the server'sContent-Rangetotal on 416; session output names keep the model's real casing;SessionOptionsnative handles are disposed. - Network & updater: Danbooru wiki previews only download HTTPS images from
donmai.ushosts with a 5 MB cap; Danbooru and GitHub requests honorRetry-Afteron 429 with one bounded retry; the update checker only accepts the win-x64 zip (no more falling back to arbitrary assets) and verifies the GitHubsha256digest after download; plain-HTTP endpoints to remote hosts now require explicit confirmation before saving. - Secrets & supply chain: a DPAPI encryption failure warns instead of silently storing the API key as plain text, and a plaintext-to-encrypted migration re-saves twice so the old plaintext also rotates out of
settings.json.bak; the bundled ffmpeg download is pinned to a fixed BtbN build and validated (archive + binary sizes) instead of following a rollinglatesttag. - Image pipeline: multi-region crop export encodes real formats per extension (webp/tif included) with atomic writes, collision-free names and no half-exported batches; the crop preview no longer leaks a full-size bitmap per region; the image editor's undo history is capped by a 512 MB byte budget instead of a fixed 15 full-bitmap snapshots; EXIF orientation is baked in on load, so camera photos stop showing (and saving) sideways; the moondream-era
Image.FromFilefile locks are gone from the remaining tools. - Files & video: deletion resolves the image's real caption extension (
.txtor.caption) and deletes videos through the same staged, rollback-capable path as images; a legal-but-empty audit transaction manifest no longer crashes dataset loading; ffprobe failures throw instead of silently reporting zeroed video info; canceled/failed conversions clean up their partial output; frame-extraction imports exclude leftovers of earlier extractions. - Translation: the whole translator chain takes a
CancellationToken, so a fallback timeout (or caller cancel) actually cancels the in-flight HTTP request instead of leaving it running in the background. - Tag list integrity: the image-tags list keeps an internal text mirror that could silently desynchronize when a grid rebind abandoned a cell-edit transaction (later bulk replace/delete then crashed with "List desynchronization detected", and the failed mutation corrupted the list further). Programmatic replace/remove now commit dangling edit transactions first, grid rebinds flush pending edits, and a detected desync self-heals (rebuilding the mirror and writing
ErrorData.jsonnext to the executable) instead of throwing mid-mutation.
UI, accessibility, i18n
- A slow multi-select tag-table build can no longer overwrite the tags of an image selected afterwards; the main window refuses to close while a batch job is running; the auto-tagger settings probes stop their timer before awaiting (no more stacked probes and duplicated lists).
- The floating preview window is an owned window instead of always-on-top: it still floats above the main window, but no longer covers modal confirmation dialogs (a hidden confirm box used to make the whole app look frozen).
- Tag grids joined the Tab order; the video tools window fits small screens (scrollable below 1080×820); LLM/ONNX/video windows close on Esc; the audit wizard is DPI-aware; search misses are announced in the status bar instead of color-only.
- LLM settings dialog on high-DPI displays: the dialog now decl...
v1.1.3
BooruDatasetTagManager+ v1.1.3
A focused file-I/O and data-safety hardening pass (fixing the 8 risks confirmed by an internal I/O audit), plus a built-in image editor with a Photoshop-style layout (zoom, pan, eyedropper), Chinese-dictionary search across both tag lists, two new CL-family ONNX tagger models (including the gated cl_tagger_v2), and a configurable double-click quick action on the All Tags grid.
Highlights
File I/O & data safety (internal audit)
- Failed saves no longer lose edits. If any tag file fails to save on exit or dataset switch (read-only file, sharing violation, disk full…), the exit/switch is blocked and the unsaved edits are kept, instead of showing an error and proceeding anyway.
- More resilient dataset loading. The new dataset must fully load before the old one is replaced and disposed, so a failed load can no longer leave the app with a half-torn-down dataset. An unreadable subfolder or a locked tag file only skips that item (tolerant enumeration), with a "loaded N, failed M" summary at the end.
- Transactional image deletion. The image and its tag file are first staged into a recycle folder and only purged once every move succeeded; any failure rolls the whole delete back, eliminating "image gone, tags left behind" half-deletes.
- Safe concurrent saving. Tag/settings writes use unique temp-file names with a per-target lock, so the main window and the LLM/ONNX windows can save simultaneously without clobbering each other. The translation cache serializes appends/rewrites and replaces the file atomically.
- Path boundary enforcement. Transaction recovery on dataset load re-validates that every recovery target stays inside the dataset folder and quarantines suspicious transaction folders; the image sorter rejects category names containing
.., path separators, or anything else that could escape the root. - Startup resilience. An unreadable Languages folder degrades to raw-key UI text with a log entry instead of crashing before the main window appears.
New: built-in image editor
Dataset context menu → Edit image opens a lightweight editor laid out like Photoshop — a slim symbol tool box on the left, an options bar on top, and a status bar with image size / zoom / tool hints:
- Tools: brush, eraser, eyedropper (click or drag to sample the brush color; dragging no longer makes the window jitter — the color swatch is redrawn in place instead of forcing a toolbar re-layout per sampled pixel), crop (drag a region, then apply), hand (pan), rotate left/right, flip horizontal/vertical, undo/redo.
- Zoom & pan: the canvas is drawn manually — mouse-wheel zoom anchored at the cursor (5%–3200%), Ctrl+0 fit to window, Ctrl+1 100%, Ctrl+± zoom steps; pan with the hand tool, the middle mouse button, or by holding Space (temporary hand, like Photoshop).
- Default Photoshop shortcuts: B brush, E eraser, I eyedropper, C crop, H hand,
[/]decrease/increase brush size, Alt+click samples a color while the brush is active, Ctrl+Z undo, Ctrl+Shift+Z / Ctrl+Y redo, Ctrl+S save, Enter apply crop, Esc cancel the crop selection. Toolbar tooltips show each shortcut. - Saving: overwrite the original (atomic write — a failed save can never truncate the source) or save an
_editcopy next to it with the caption file cloned so the copy keeps its tags. The default action (ask / overwrite / new file) is configurable under Settings → UI → "Image editor: default save action".
New ONNX models: the cl_tagger family
- [CL] v1.02 —
Nonene/cl_tagger(public mirror; WD EVA02 fine-tune, 448px). Preprocessing follows the author'sonnx_predict.py: white-padded square, BGR,(x/255−0.5)/0.5, NCHW; raw logits pass through a numerically stable sigmoid; labels come fromtag_mapping.json(index → tag/category). Default thresholds 0.45 / 0.45. - [CL] v2.00 / v2.01a 🔒 —
cella110n/cl_tagger_v2(SigLIP2-so400m, 384px, ~107-108k tags; both variants selectable, each downloading from its own repo folder). Direct 384×384 bicubic resize, RGB, same normalization; labels frommodel_vocabulary.json; downloads include themodel.onnx.dataexternal-weights sidecar. Default threshold 0.55. - Gated-repo handling: cl_tagger_v2 ships under the author's custom license that forbids redistribution, public re-hosting and bundled distribution — the app never bundles it. Before downloading, a notice summarizes the license and gating: log in to HuggingFace, accept the terms on the model page, request access, and enter your own access token (persisted DPAPI-encrypted like the API keys, sent as a Bearer header). A 401/403 response shows guidance, and manually downloaded files placed in the local
Models/folder are picked up as-is. - Per-model thresholds are stored under the catalog id, WD-style; both models run on DirectML with automatic CPU fallback and get the same corrupt-model detection (load-is-the-check, purge and re-download).
All Tags: double-click quick action & selection fix
- Double-click quick action — single click selects, double-click runs a configurable action. Default: open "Replace all" with the double-clicked tag preselected as the source. Settings → General offers the All Tags toolbar functions instead: add/remove the tag on all / selected / filtered images, or filter images by the tag.
- Selection no longer jumps after re-sorts — with the list sorted by count, adding/removing a tag on other images re-sorts the list, and the grid used to keep the selection by row index, silently landing on a different tag. The selection is now anchored by tag text and restored after every list reset (multi-selection included).
Tag search understands the Chinese dictionary
- Both the All Tags search box and the new Image Tags search box match with the priority English prefix > English substring > translation column >
danbooru-0-zh.csvdictionary (synonyms included) — typing 头发 locates long hair, black hair, … even before online translations have loaded. - The new Image Tags box mirrors the All Tags behavior: typing locates the first match, Enter jumps to the next one, Esc (or the clear button) resets, and a no-match query tints the box instead of silently eating keys. In multi-select view, continuation rows match through their group's tag text.
UI & localization fixes
- Settings overlap fixed. The "Image editor: default save action" row on the Settings → UI tab overlapped its neighbor rows on high-DPI displays (controls added at runtime are excluded from WinForms auto-scaling); the row is now positioned relative to the already-scaled controls, so it stays on its own line and column-aligned at any DPI.
- Dataset column names fully localized. The dataset header right-click menu (column show/hide) previously mixed translated and raw property names; the File path / Image modified time / Tags modified time columns are now localized in all five languages, and the Image / Name columns gain proper zh-TW / ru-RU / pt-BR translations.
- Clearer folder-loading menu name. "Load folder with additional settings…" is renamed "Load Folder (Custom Options)…", so the two File-menu entries share the same prefix and the parenthetical marks the difference; the options dialog is retitled "Folder load options", and its checkboxes gain proper zh-TW / pt-BR translations.
Docs
- The trilingual READMEs (zh / en / pt-BR) are restructured into five sections — changelog first, then quick start (install + build from source), a features table, and the per-feature guide; per-release details stay in
docs/RELEASE_NOTES_*.md.
Tests
- 69 new regression tests in this release: fault-injection I/O tests (save-failure, load-failure, delete-rollback, concurrency, path-escape, startup scenarios) plus image editor, tolerant enumeration, file deleter, tag-search suites (Chinese dictionary lookup, alias/translation match priority, wrap-around) and CL model coverage (tag_mapping/vocabulary parsing, stable sigmoid, normalization, catalog/gating flags, nested-path cache validation).
- 333 / 333 unit tests passing.
Verification
dotnet build BooruDatasetTagManager/BooruDatasetTagManager.csproj— 0 errorsdotnet test BooruDatasetTagManager.Tests— 333 / 333 passing- Rendered-UI checks: main window (Image Tags search box), image editor (zh-CN, compact tool box + zoom status), Settings → General/UI tabs (new quick-action row, no overlap), gated-model notice dialog
- cl_tagger preprocessing verified against the author's
onnx_predict.py(celll1/tagutl) and the cl_tagger_v2 model card; actually running the models requires downloading them (v2 additionally requires your own approved HuggingFace access)
Install
Download BooruDatasetTagManagerPlus-1.1.3-win-x64.zip from Releases, extract, and run BooruDatasetTagManagerPlus.exe.
Self-contained build for Windows x64; no separate .NET install required.
Local runs create Models/, Cache/, and settings.json next to the executable — locally generated data that is safe to delete (models can be re-downloaded from inside the app).
更新摘要(中文)
文件 I/O 与数据安全(内部审计 8 项修复)
- 保存失败不再丢编辑:关闭程序或切换数据集时若有标签文件保存失败(只读、被占用、磁盘满等),将阻止退出/切换并保留未保存的修改,而不是提示错误后照常继续
- 加载数据集更稳:新数据集完整加载成功后才替换并释放旧数据集;无权限子目录、被锁定的标签文件等只跳过该项(容错枚举),加载结束后汇总提示「成功 N、失败 M」
- 删除图片事务化:图片与同名标签文件先移入暂存回收目录、全部成功才清理,任一失败自动回滚,杜绝「图片已删、标签残留」的半删除
- 并发写盘安全:标签/设置保存改用唯一临时文件名并按目标加锁,主窗口与 LLM/ONNX 窗口同时保存不再互相覆盖;翻译缓存的追加与重写统一加锁并原子替换
- 路径边界防护:打开数据集时的事务恢复会重新校验恢复目标必须位于数据集目录内,异常事务目录自动隔离;图片分类器拒绝含
..、路径分隔符等可逃逸根目录的分类名 - 启动容错:语言目录不可读时降级为原始键显示并记录日志,不再在主窗口出现前崩溃
新增:内置图片编辑器
- 数据集右键「编辑图片」打开轻量编辑器,仿 Photoshop 布局:紧凑左侧工具栏 + 顶部选项栏 + 底部状态栏(尺寸 / 缩放 / 工具提示)
- 工具:画笔、橡皮擦、吸管(点击或拖动取色;拖动取色不再引起窗口抖动——色块就地重绘,不再每个像素触发工具栏重布局)、裁切(拖选区域后应用)、抓手(平移)、...
v1.1.2
BooruDatasetTagManager+ v1.1.2
Security, stability, and performance hardening pass. No workflow or UI changes.
Highlights
Crash fixes
- Preview-tab hotkey no longer crashes. After the AutoTagger preview tab was removed, the "focus preview tab" hotkey still selected tab index 2 (out of range for the remaining two tabs) and crashed; it now targets the correct tab and moves to Ctrl+4, and the orphaned Ctrl+4 "focus AutoTagger preview" hotkey was removed. In the same pass, missing/stale localization was fixed across all five languages: the save-error dialog no longer shows a raw
TipSaveErrorskey, the two unlocalized translation-service names and the Traditional-Chinese language-menu entry display properly, built-in prompt-template names localize in the LLM tagging window, the "Tagging settings…" dialog gets its own title, and dead keys from the removed TAG2NL/AutoTagger-preview/server-based background-removal flows were deleted. - Deleting tagged images no longer crashes. The dataset grid is bound to a plain
List<DataItem>, which does not raise change notifications; after removing rows the grid kept stale entries with null cells, throwingIndexOutOfRangeExceptionon paint and then a repeatedArgumentNullException(null key) inLoadSelectedImageToGrid. The grid now re-reads its row count viaCurrencyManager.Refresh(), and the tag-loading code guards against stale/removed rows. - Deleting several images at once no longer crashes with
ImageAnimator"Parameter is not valid". A PictureBox was being asked to animate an already-disposed image onWM_SHOWWINDOW. Two causes were fixed: (1)GetImageFromFileWithCachecould return a disposed shared instance when a concurrent removal disposed the cache entry mid-clone — the cache now clones under its own lock (TryGetClone) and never hands out the shared instance; (2) the main-window and separate preview PictureBoxes now detach the previous image before disposing it, so a later show never animates a disposed image.
Security
- Tag database format.
List.tdbis now serialized with JSON (Newtonsoft.Json) instead ofBinaryFormatter, removing a deserialization code-execution risk. Legacy/corrupt caches fail safe and rebuild from the source CSV/txt. - API key at rest. The OpenAI-compatible API key in
settings.jsonis encrypted with Windows DPAPI (CurrentUserscope). Existing plaintext keys are read once and re-written encrypted on the next save. - External-call hardening.
- ffmpeg is invoked via
ProcessStartInfo.ArgumentList(per-argument escaping) instead of a hand-quoted command string. - Google-translate queries are URL-encoded; the broken manual HTML-entity decoder was removed.
- HuggingFace download paths are validated to stay inside the
Models/directory (path-traversal guard).
- ffmpeg is invoked via
- AiApiServer hardening.
- The server now binds to
127.0.0.1by default; pass--listento accept remote connections and--portto change the port (default 50051). - Optional
--api-key <key>requires every request to carry a matchingX-Api-Keyheader. The client sends it automatically whenAutoTagger.ApiKeyis set insettings.json(stored DPAPI-encrypted like the OpenAI key). VIDEO_PATHrequests are validated (no..segments, video-extension whitelist, file must exist) before the path reaches a model.- Request bodies are capped at 512 MB (
MAX_CONTENT_LENGTH), preventing memory-exhaustion payloads. - Served by multi-threaded waitress (added to
requirements.txt) so status endpoints stay responsive during long inference; falls back to the Flask dev server if waitress is missing. - The three copy-pasted OOM-retry blocks were unified into
force_unload_all(), and bareexcept: passhandlers now log failures.
- The server now binds to
- DPAPI decryption feedback. If a stored key cannot be decrypted (settings copied from another machine or user account), the app now shows a localized warning at startup asking to re-enter the key instead of silently presenting an empty field.
Stability
- Change detection. "Unsaved changes" is now order-independent (a structure signature over the key set) and per-item modification uses exact tag-text comparison instead of a 32-bit hash, so edits can no longer collide and be silently dropped or falsely flagged.
SaveAllresets each item's saved snapshot after a successful write. - Bounded image cache. The preview/thumbnail cache is a capacity-limited LRU that disposes evicted images (previously an unbounded dictionary that never released GDI handles). Callers receive an independent clone, so an eviction can never dispose an image still bound to a control.
- Settings load.
AppSettings.LoadDatanow retries a bounded number of times and handles write failures instead of looping, falling back to defaults when a settings file cannot be recovered. - Delete feedback. File-delete failures are logged and surfaced to the user; only successfully deleted items are removed from the dataset, keeping on-disk and in-memory state consistent.
- Deterministic dataset teardown.
DatasetManagerimplementsIDisposable; opening a new folder unbinds the grid and disposes every thumbnail of the previous dataset instead of leaving thousands of GDI+ bitmaps to finalizers (which could exhaust the process GDI-handle limit on repeated folder switches). - Preview images always disposed. The main-window and separate-window previews previously leaked the old image whenever image caching was enabled (the default); since the cache hands out caller-owned clones, the old image is now disposed on every swap. The transparent-background tool also disposes replaced thumbnails.
- RemoveMany count consistency. Global tag counts are now decremented only after an item is actually removed from the dataset, so a concurrent removal can no longer leave
AllTagscounts out of sync.
Crash & data-safety hardening (full-codebase audit)
A dedicated crash/IO audit of the whole codebase (~37k lines, client + AI server) produced a second round of systematic fixes:
- Global exception backstop.
Application.ThreadException,AppDomain.UnhandledException, andTaskScheduler.UnobservedTaskExceptionare now registered; unhandled errors are appended tocrash.log(falling back to%LOCALAPPDATA%on read-only installs) and surfaced as a localized dialog instead of silently terminating the process. - Startup chain resilience. A corrupt/missing
ColorScheme.json, language file, orsettings.jsonno longer hard-crashes before any window exists: broken files are backed up as.corruptand defaults are used; an unknown UI culture or missing language falls back toen-US; a failed tag-database load shows an error instead of leaving the splash screen open forever. Tag CSV loading tolerates per-file failures and count overflows. - Atomic writes everywhere it matters. New
SafeFilehelper (temp file +File.Replace): dataset.txtsaves can no longer be truncated by a locked file or full disk, one failed file no longer abortsSaveAll(failures are listed and stay marked modified), andsettings.jsonis written atomically with a.bak(a mid-write crash used to silently reset all settings, including API keys). - Batch tools never destroy sources. Crop, background removal, and transparent-background replacement encode to a temp file and swap only on success; per-image failures are skipped and reported; all five batch operations now release the UI lock in
finally(an error used to leave the entire window permanently disabled). The transparent-background tool also stops reading UI controls from its worker thread. - Closing mid-job is safe. The ONNX tagger, video tools, video convert, and character-audit wizard defer a close requested while a job runs (cancel + close after the job unwinds), eliminating an uncatchable native AccessViolation (ONNX session disposed under an in-flight
Run) and thread-poolObjectDisposedExceptionprocess kills. Progress callbacks are marshaled through a shared dispose-safe helper. - Cancellation actually cancels.
Process.WaitForExitAsync(token)replaces an uncancellable wait, so cancelling a conversion/extraction really kills the ffmpeg child (it used to keep running and writing to disk for minutes). Cancelling an ONNX batch now applies and saves the tags of images already processed instead of discarding everything. - "Replace original" conversion fixed. It used to pass the input file as ffmpeg's output (
-ytruncates the output before reading — guaranteed failure on modern ffmpeg, source destruction on old builds). Conversion now writes_convert_tmpand atomically replaces the original on success;ConvertAsyncadditionally rejects identical input/output paths. - Locale-safe prompt weights.
(tag:1.1)weight parsing uses invariant culture (it used to throwFormatExceptionfor every weighted dataset on decimal-comma locales such as ru-RU/de-DE); malformed weights fall back to 1. - Interruption-safe model downloads. HuggingFace downloads write to
.partialand are renamed only after a Content-Length check; a truncatedmodel.onnx(>1 MB) can no longer masquerade as a valid cached model and permanently break tagging. A run/download re-entrancy race in the ONNX dialog was also closed. - Integrity check before use. All local models (WD14, PixAI, background removal) are integrity-checked at load time — loading the ONNX session (and parsing the csv/json sidecars) is the check. A corrupt or incomplete file throws
OnnxRuntimeException, which the service catches, deletes the bad file(s), and rethrows as a localizedModelCorruptedExceptionso the caller re-downloads a clean copy (the background-removal dialog auto-retries the download once; the ONNX tagger re-prompts on the next run). Genuine environment errors (missing native runtime, unsupported input precision) are excluded so a valid model is never wrongly dele...
v1.1.1
BooruDatasetTagManager+ v1.1.1
Highlights
Character tag audit save
- Faster apply-and-save: manifest written once per transaction instead of per file
- In-memory tag updates batched via
ExecuteBulkMutationto avoid AllTags refresh storms - Save progress UI (preparing / saving files / updating index)
- Lighter post-save refresh without re-triggering translation
Unified crop image
- Single menu entry Crop image replaces separate single-crop and multi-crop flows
- Draw one or many regions on the canvas; live preview panel with dimensions
- Export to the same folder as the source image:
{basename}_r1,_r2, … (original untouched) - Cropped files are auto-imported into the loaded dataset after export
Install
Download BooruDatasetTagManagerPlus-1.1.1-win-x64.zip from Releases, extract, and run BooruDatasetTagManagerPlus.exe.
Self-contained build for Windows x64; no separate .NET install required.
Local runs create Models/, Cache/, and settings.json next to the executable. These are runtime-only and are not committed to Git.
更新摘要(中文)
- 角色标签审查「应用并保存」加速:减少 manifest 写入、批量更新 AllTags、保存进度提示
- 统一「裁剪图片」:单次与多重裁切合并;导出到原图同目录
{basename}_r1/_r2;不覆盖原图 - 裁切完成后自动将新图片导入当前数据集
See v1.1 release notes for ONNX tagging and model reliability improvements.
v1.1
BooruDatasetTagManager+ v1.1
Highlights
ONNX tagger and models
- Full WD14 catalog (12 models) in the model picker, including vit-large v3 and eva02-large v3
- PixAI v0.9 fix — selects
prediction/logitsoutput correctly; v0.9 CSV format; WebP via ImageLoader; DirectML failure falls back to CPU - Per-model WD14 thresholds — vit-large default 0.26 no longer inherits eva02-large 0.52 when reopening or switching models
- WD14 large-model inference: DirectML hang recovery via CPU retry; explicit output tensor name; NHWC / NCHW input size detection
Batch tagging and UI
- Split ONNX inference (background) from tag writes (UI thread); fixes batch
BindingSourcecircular-reference errors - Progress bar shows last / average / ETA / elapsed inference time
- Model download completion dialog; status resets to ready-to-tag
- Post-batch
SaveAllruns in background; single-image selection uses synchronous tag grid refresh to reduce UI freezes
Install
Download BooruDatasetTagManagerPlus-1.1-win-x64.zip from Releases, extract, and run BooruDatasetTagManagerPlus.exe.
Self-contained build for Windows x64; no separate .NET install required.
Local runs via test_start.bat or quick_build.bat create Models/, Cache/, and settings.json next to the executable. These are runtime data and are not committed to Git; download ONNX models from inside the app.
更新摘要(中文)
- WD14 全系列 12 款模型可选;PixAI v0.9 推理修复(多输出张量、CSV、WebP、DirectML 回退 CPU)
- WD14 按模型独立阈值(vit-large 0.26 不再误用 eva02 的 0.52);大模型 DirectML 挂起时自动回退 CPU
- 批量推标修复 BindingSource 错误;进度条显示推理耗时与 ETA
- 模型下载完成提示;推标结束后后台保存、单图同步刷新标签列表
- 本地
Models/、Cache/、settings.json为运行时数据,不入库
See v1.0.5 release notes for the previous major ONNX / video release.
v1.0.5
BooruDatasetTagManager+ v1.0.5
Highlights
ONNX tagger
- Unified dialog for WD14 (eva02-large v3) and PixAI 0.9
- HuggingFace official / HF mirror model download
- Separate general and character thresholds; write modes and optional tag sort
- Tag post-processing: underscore→space (ONNX only), prefix/suffix tags
- Right-click Retag with ONNX opens the dialog with progress bar and auto-starts
Inference fixes
- WebP images load through
ImageLoaderinstead of GDI+Bitmap - WD14 v3
selected_tags.csvformat parsing fixed - Preprocessing aligned with official SmilingWolf wd-tagger (padding, bicubic resize, dual thresholds)
Video tools
- Video format conversion — mp4, mkv, avi, webm, mov, flv; optional replace original
- Frame extraction — all frames, by FPS, native FPS, or specific frames with preview and lock-frame workflow
- FFmpeg bundled in Release builds (
scripts/fetch_ffmpeg.ps1on first local build)
UI cleanup
- Removed file-browse input sources from ONNX and video tools
- Removed obsolete comma-separated hint from ONNX settings
Install
Download BooruDatasetTagManagerPlus-1.0.5-win-x64.zip from Releases, extract, and run BooruDatasetTagManagerPlus.exe.
Self-contained build for Windows x64; no separate .NET install required.
更新摘要(中文)
- 统一 ONNX 推标(WD14 eva02-large v3 + PixAI 0.9),HuggingFace / 镜像下载,双阈值与写入模式
- 修复 WebP 推理崩溃、v3 标签 CSV 解析、官方预处理对齐
- 标签后处理:下划线→空格(仅 ONNX)、前缀/后缀标签
- 右键 ONNX 重新推标显示进度条并自动开始
- 视频格式转换与视频抽帧(预览、锁定帧、原生 FPS);Release 内置 FFmpeg
- 界面精简:移除文件浏览输入源与无用提示
v1.0.4
BooruDatasetTagManager+ v1.0.4
面向 LoRA / 角色数据集的 Windows 标签管理工具。自包含发布包,解压即用,无需单独安装 .NET 8。
安装
- 下载
BooruDatasetTagManagerPlus-1.0.4-win-x64.zip - 解压到任意目录
- 运行
BooruDatasetTagManagerPlus.exe - 首次启动默认为简体中文界面;在 LLM 设置 中配置 OpenAI 兼容端点后再使用打标 / TAG2NL / 审查功能
本版本亮点
LLM 设置重构
- 统一 LLM 连接(地址、密钥、超时、文本模型)
- 视觉模型分离:自动打标 / 角色审查可独立选择
- TAG2NL 并发数与固定提示词配置
新功能
- LLM 打标 — 对全部图片批量 AI 视觉打标
- TAG2NL — 标签 + 图片 → 自然语言描述,输出至
_captioned目录 - 角色标签审查 — 触发词 + 标准图 + 全库 inventory,AI 两阶段审查后写回数据集
- 四套内置打标提示词模板 + 自定义导入导出
改进
- 中文 Danbooru 映射、Wiki 弹窗、审查理由本地化
- 源数据只读;写盘支持取消、单文件失败隔离与事务回滚
- 仓库不再包含
dist/二进制,请从此 Release 下载
系统要求
- Windows 10/11 x64
- 使用 LLM 功能需自备 OpenAI 兼容 API 端点
致谢
基于 starik222/BooruDatasetTagManager 独立扩展维护。
BooruDatasetTagManager+ v1.0.4 (English)
Windows tag manager for LoRA / character datasets. Self-contained build — extract and run; no separate .NET install.
Install
- Download
BooruDatasetTagManagerPlus-1.0.4-win-x64.zip - Extract anywhere
- Run
BooruDatasetTagManagerPlus.exe - Default UI language is Simplified Chinese; configure an OpenAI-compatible endpoint under LLM Settings before tagging / TAG2NL / audit
Highlights
- Refactored LLM Settings (connection, vision models, TAG2NL concurrency)
- LLM tagging for all images, TAG2NL caption export, character tag audit wizard
- Four built-in prompt templates + custom JSON import/export
- Binaries are no longer in the git repo — download from this Release
Requirements
- Windows 10/11 x64
- OpenAI-compatible API endpoint for LLM features
Forked and extended from starik222/BooruDatasetTagManager.