labelminus

package module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 3, 2026 License: BSD-2-Clause Imports: 20 Imported by: 0

README

LabelMinus

LabelMinus 是 LabelPlus 与 LabelPlusFX_New 对应的命令行工具。

安装

go install github.com/syriku/LabelMinus/cmd/labelminus@latest

项目宗旨

为了应对 agent 浪潮,让 AI agent 也能通过 CLI 来创建漫画翻译文件,而无需依赖 GUI 应用。LabelMinus 旨在提供与 LabelPlus / LabelPlusFX_New 兼容的翻译文件格式读写能力,使自动化工作流与 agent 协作成为可能。

功能

创建翻译文件(--dir / -d)
labelminus -d <图片目录> [图片名...] [-o <输出文件>]
  • 不提供图片名时,自动扫描目录的直接内容(不递归子目录),找出所有以“数字.图片扩展名”结尾的文件(仅紧挨扩展名的数字段作为页码),按页码升序收入。
  • 也可以显式给出若干个图片文件名(相对该目录),此时只校验图片格式、不校验数字结尾规则,也不重新排序。
  • 支持的图片扩展名:.jpg / .jpeg / .jpe / .png。
  • 每张图片成为翻译文件中的一个图片块。默认输出到“目录名.txt”,目标已存在时报错中止,不会覆盖。
编辑翻译文件(--proj / -p)
labelminus -p <翻译文件[.txt]>                              # 输出解析后的文件路径

# 页(图片块)编辑
labelminus -p <翻译文件> insert <n> <图片名>                # 在第 n 页之前插入一页(n == 页数 时追加)
labelminus -p <翻译文件> delete <n>                         # 删除第 n 页

# 页内标签编辑
labelminus -p <翻译文件> tag   <页> <种类> <x> <y> [文本...]           # 添加标签
labelminus -p <翻译文件> untag <页> <种类> <编号>                      # 删除标签(种类用于交叉校验)
labelminus -p <翻译文件> retag <页> <种类> <编号> <x> <y> [文本...]    # 重设标签的种类/位置/文本
  • 编辑会直接修改并保存翻译文件。
  • 页、种类、标签编号在参数中一律从 0 开始;文件里的种类号与标签序号从 1 开始(参数 = 文件编号 - 1)。不同种类的标签共用页内计数器,标签编号即在页内的序号。
  • x / y 为小数坐标(通常为 0~1 的相对坐标);标签文本可省略(空文本),含空格时建议整体用引号包裹。
  • insert 的图片名只校验图片格式,不要求“数字结尾”的扫描命名规则。
打出标签参考图(view)
labelminus -p <翻译文件> view [--page <n>] [-o <输出目录>]
  • 把各页图片连同标签标记一起打出,用来参考标签的位置到底对不对:每个标签位置处绘制彩色圆标记,颜色按种类(分组)分配(与 LabelPlusFX 的默认配色一致),圆内数字是文件中的标签序号(1 开始;CLI 参数中的编号 = 序号 - 1)。
  • 图片相对翻译文件所在目录解析。部分页缺图时尽可能打出其余页(警告并跳过);所有指定页都缺图时报错。
  • --page <n> 只打出第 n 页(0 开始);不给出时尽可能打出所有页。
  • 默认输出到工作目录下的 .tmp/manga-view/;输出目录中同名文件会被覆盖。输出目录不允许与翻译文件所在目录相同(避免覆盖原图)。
清理图片(clean)
labelminus clean [目录] [-y]
  • 删除指定目录直接内容(不递归子目录)中所有支持的图片格式(.jpg / .jpeg / .jpe / .png,不区分大小写)的文件,不校验图片是否来自本项目。
  • 不提供目录时,默认清理 view 子命令的默认输出目录 .tmp/manga-view/。
  • 删除前先列出待删除文件总表并要求输入 y 确认(默认 N);-y / --yes 跳过确认直接删除。
  • clean 是独立子命令,不能与 --dir / --proj / --output / --page 混用。

完整说明见 labelminus --help。

已知限制

  • 通过 LabelMinus 创建的翻译文件只包含“框内”“框外”两种标签分类(与 LabelPlus 系新建项目的默认分组一致),暂无创建 / 增删分组的命令。这是已知状况,但暂时没有动力去修改。

项目结构

  • 根包 package labelminus:核心库,实现图片扫描、路径解析、翻译文件编辑等所有业务逻辑。
  • labelplus:LabelPlus 翻译文件(LP 格式)的数据模型与解析 / 导出。
  • cmd/labelminus:CLI 入口,不直接实现业务逻辑,所有功能来自核心库。

构建

go build ./cmd/labelminus

开发中

本项目目前处于早期开发阶段,API 与命令行接口可能随时变动。

Documentation

Overview

Package labelminus is the core library of LabelMinus.

Index

Constants

View Source
const DefaultViewDir = ".tmp/manga-view"

DefaultViewDir 是 view 子命令的默认输出目录(相对工作目录)。

View Source
const ProjExt = ".txt"

ProjExt 是 LabelPlus 翻译文件的扩展名。

Variables

View Source
var SupportedImageExts = []string{".jpg", ".jpeg", ".jpe", ".png"}

SupportedImageExts 是支持的图片扩展名列表(小写、含点)。

Functions

func CollectImages

func CollectImages(dir string, names []string) ([]string, error)

CollectImages 汇总 --dir 模式最终交给后端库的图片路径数组。 names 为用户显式提供的图片文件名(相对 dir);为空时自动扫描 dir 的直接内容。返回的数组元素保持相对路径(不含 dir 前缀), 一般情况下就是纯文件名。

显式提供的图片名只校验是否为支持的图片格式(IsSupportedImageName), 不校验“数字结尾”命名规则、也不重新排序(规则与排序仅对自动扫描生效)。

func DefaultProjPath

func DefaultProjPath(dir string) string

DefaultProjPath 返回 --dir 模式的默认输出路径: 保存在 dir 的直接内容中,文件名为 dir 最后一级目录名 + .txt。

func DeleteImages

func DeleteImages(dir string, names []string) ([]string, error)

DeleteImages 删除 dir 下 names 指定的文件(不含目录前缀, 通常来自 ScanSupportedImages)。 尽可能删除所有文件:单个文件删除失败不会中断其余文件的删除, 全部失败会以 errors.Join 汇总为返回值中的 error。 返回成功删除的文件名列表(保持传入顺序)。

func ExportDirProject

func ExportDirProject(dir string, names []string, output string) (string, error)

ExportDirProject 是 --dir 模式的核心流程: 汇总图片列表(names 为空时自动扫描 dir),据此创建 LabelPlus 翻译文件(每张图片成为一个图片块),导出并保存为文件。 返回最终写入的文件路径。

为避免覆盖已有翻译成果,目标文件已存在时报错中止。

func IsNumberedImageName

func IsNumberedImageName(name string) bool

IsNumberedImageName 判断文件名(不含路径)是否符合 numberedImageRe 规则。

func IsSupportedImageName

func IsSupportedImageName(name string) bool

IsSupportedImageName 判断文件名是否具有支持的图片扩展名(不区分大小写)。 只校验扩展名;“数字结尾”等命名规则仅对自动扫描生效 (见 IsNumberedImageName),手动指定的图片名不受其约束。

func NormalizeProjName

func NormalizeProjName(name string) string

NormalizeProjName 将输出文件名规范化为只带一个 .txt 后缀的形式: 先去掉末尾所有重复的 .txt(不区分大小写),再补上一个。 例如 "out" -> "out.txt","out.txt.txt" -> "out.txt"。

func ResolveOutputPath

func ResolveOutputPath(dir, output string) string

ResolveOutputPath 计算最终输出路径: output 为空时使用 DefaultProjPath(dir 内、以目录名命名); 否则将 output 规范化为单个 .txt 后缀后按给定路径使用。

func ResolveProjFile

func ResolveProjFile(path string) (string, error)

ResolveProjFile 解析 --proj 给出的翻译文件路径: 若未提供 .txt 扩展名则自动补上,然后确认该文件确实存在 (存在但不是普通文件也视为错误)。返回最终可用的文件路径。

func ScanNumberedImages

func ScanNumberedImages(dir string) ([]string, error)

ScanNumberedImages 扫描 dir 的直接内容(不递归子目录), 返回所有符合 IsNumberedImageName 规则的文件名(不含目录前缀), 按结尾数字的大小升序排序。 找不到时返回错误。

func ScanSupportedImages

func ScanSupportedImages(dir string) ([]string, error)

ScanSupportedImages 扫描 dir 的直接内容(不递归子目录), 返回所有支持的图片格式(IsSupportedImageName)的文件名 (不含目录前缀),按文件名字典序排序。 扫描不到时返回空列表,不视为错误。

Types

type ProjEditResult

type ProjEditResult struct {
	// Path 是实际写入的翻译文件路径(经 ResolveProjFile 规范化)。
	Path string

	// PicName 是被插入 / 删除的图片名。
	PicName string

	// PicCount 是编辑后的总页数。
	PicCount int
}

ProjEditResult 是一次翻译文件页编辑(insert / delete)的结果。

func DeleteProjPic

func DeleteProjPic(projPath string, n int) (*ProjEditResult, error)

DeleteProjPic 删除翻译文件 projPath 的第 n 页(0-based, 0 <= n < 页数),并保存翻译文件。

func InsertProjPic

func InsertProjPic(projPath string, n int, imageName string) (*ProjEditResult, error)

InsertProjPic 在翻译文件 projPath 的第 n 页(0-based)之前插入一页 图片 imageName(n == 页数 时追加到末尾),并保存翻译文件。

imageName 必须是支持的图片格式(IsSupportedImageName); 手动添加的图片名不要求遵循“数字结尾”的自动扫描命名规则。

type ProjTagResult

type ProjTagResult struct {
	// Path 是实际写入的翻译文件路径(经 ResolveProjFile 规范化)。
	Path string

	// PicName 是所在页的图片名。
	PicName string

	// Label 是被添加 / 删除 / 更新后的标签。
	Label labelplus.Label

	// Number 是标签在页内的编号(0-based,不同种类的标签共用
	// 页内计数器,文件中显示为 Number + 1)。
	Number int
}

ProjTagResult 是一次标签编辑(tag / untag / retag)的结果。

func RetagProjPic

func RetagProjPic(projPath string, page, group, number int, x, y float64, text string) (*ProjTagResult, error)

RetagProjPic 将翻译文件 projPath 第 page 页(0-based)内编号为 number(0-based)的标签重新设置为新的种类 group(0-based)、 位置 (x, y) 与文本 text,并保存翻译文件。 编号本身即可唯一定位标签,无需提供原种类。

func TagProjPic

func TagProjPic(projPath string, page, group int, x, y float64, text string) (*ProjTagResult, error)

TagProjPic 在翻译文件 projPath 的第 page 页(0-based)添加一个 种类为 group(0-based,必须在已声明分组范围内)、位置 (x, y)、 文本为 text 的标签,并保存翻译文件。

func UntagProjPic

func UntagProjPic(projPath string, page, group, number int) (*ProjTagResult, error)

UntagProjPic 删除翻译文件 projPath 第 page 页(0-based)内编号为 number(0-based)的标签,并保存翻译文件。编号本身即可唯一定位标签, group 是期望的种类标号(0-based),仅用于交叉校验,防止误删。

type ViewGroupInfo

type ViewGroupInfo struct {
	// Index 是分组的 0-based 索引(即 CLI 参数中的“种类”编号)。
	Index int

	// Name 是分组名。
	Name string

	// Color 是分配给该分组的颜色(十六进制 RGB,不含 '#'),
	// 与 LabelPlusFX 的默认分配规则一致(见 labelplus.DefaultGroupColor)。
	Color string
}

ViewGroupInfo 是 view 子命令输出的分组颜色图例信息。

type ViewResult

type ViewResult struct {
	// Dir 是实际打出图片的目录。
	Dir string

	// Rendered 是成功打出的图片文件名(与翻译文件中的图片名一致),
	// 按页序排列。
	Rendered []string

	// Missing 是因图片文件缺失或无法解码而跳过的页的图片名,
	// 按页序排列。
	Missing []string

	// Groups 是分组颜色图例(图中标记颜色按此分配)。
	Groups []ViewGroupInfo
}

ViewResult 是 view 子命令的结果。

func ViewProject

func ViewProject(projPath, outputDir string, page int) (*ViewResult, error)

ViewProject 是 view 子命令的核心流程: 解析翻译文件 projPath,把各页图片连同标签标记一起打出到 outputDir。 图片相对翻译文件所在目录解析;page 指定只打出第 page 页(0-based), page < 0 时打出所有页。

打出的图片内容:原图 + 每个标签位置处的圆形标记。标记颜色按标签 种类(分组)分配,圆内数字是文件中的标签序号(1-based,即 CLI 子命令参数中的编号 + 1)。

缺图处理:部分页缺图时尽可能打出其余页(记入 Missing 并 log 警告); 所有指定页都缺图时报错。输出目录中的同名文件会被覆盖。 outputDir 为空时使用 DefaultViewDir(相对当前工作目录)。 为防止覆盖原图,outputDir 不允许与翻译文件所在目录相同。

Directories

Path Synopsis
cmd
labelminus command
Command labelminus is the CLI of LabelMinus.
Command labelminus is the CLI of LabelMinus.
Package labelplus 提供 LabelPlus 翻译文件(LP TXT 格式)的核心数据模型与读写能力。
Package labelplus 提供 LabelPlus 翻译文件(LP TXT 格式)的核心数据模型与读写能力。

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL