CLI-Anything Krita 深度指南:用命令行与 JSON 项目状态驱动 Krita 实现绘画流程自动化
【免费下载链接】CLI-Anything"CLI-Anything: Making ALL Software Agent-Native" -- CLI-Hub: https://clianything.cc/项目地址: https://gitcode.com/GitHub_Trending/cl/CLI-Anything
导读
cli-anything-krita是 CLI-Anything 为Krita(专业开源数字绘画软件)打造的 CLI 适配层(harness):它以"Project JSON + 真实 Krita 渲染引擎"为核心,把新建项目、图层管理、滤镜应用、画布调整、导出渲染等操作全部变成可复现、可脚本化、可被 AI Agent 调用的命令行原语。读完本文,你将掌握如何安装并运行这套工具、理解 Project JSON 的数据结构与命令组设计、熟悉每个命令的参数与导出预设,并透过源码看清.kra文件生成与 Krita 无头导出的底层原理,从而把 Krita 接入自动化流水线或 Agent 工作流。
项目定位:CLI 是 Krita 的"遥控器"而非替代品
Krita 本身是带 GUI 的桌面绘画软件,其可执行文件支持--export等无头参数,但没有一套完整、结构化的工程化操作接口。cli-anything-krita的价值在于提供一层统一的命令行界面:
- 以Project JSON保存文档状态(画布尺寸、色彩空间、位深、图层栈、滤镜、元数据);
- 由 JSON 状态构建合法
.kra文件; - 调用真实 Krita 的
--export/--export-sequence完成渲染; - 对导出结果做输出校验(检查文件是否生成、大小等信息)。
正如 README 结尾所强调:The CLI is an interface TO Krita, not a replacement. All rendering is done by Krita's engine.——本项目负责"如何描述一次作画任务",而像素渲染与滤镜计算全部由 Krita 自身引擎完成。这一点也决定了系统的边界:机器上必须装有可被调用的 Krita 可执行文件。
环境准备与安装
前置条件
- Python 3.10+(见 setup.py 的
python_requires=">=3.10"); - 系统已安装Krita,支持三种平台安装方式:
- Windows:从官方下载页获取安装包;
- macOS:
brew install --cask krita; - Linux:
sudo apt install krita或flatpak install org.kde.krita。
安装 CLI
仓库中以源码方式分发,在krita/agent-harness目录下以可编辑模式安装即可:
cd krita/agent-harness pip install -e .该包的元信息定义在 setup.py 中:包名cli-anything-krita、版本1.0.0,运行依赖为click>=8.0.0与prompt-toolkit>=3.0.0(后者用于交互式 REPL 皮肤),并通过entry_points将cli-anything-krita命令注册为cli_anything.krita.krita_cli:main。
Krita 可执行文件的自动发现
CLI 并不假设 Krita 的具体安装位置,krita_backend.py 中的find_krita()按以下顺序查找:
- 环境变量
KRITA_PATH(显式覆盖,指向可执行文件绝对路径); PATH中的krita/krita.exe(shutil.which);- Windows 常见安装目录的 glob 匹配(
C:/Program Files/Krita*/bin/krita*.exe等); - macOS 应用包路径
/Applications/krita.app/Contents/MacOS/krita。
全部查找失败会抛出带有安装指引的RuntimeError。版本探测则通过运行krita --version并解析输出获得(如"5.2.2")。
两种使用形态:一次性命令与交互式 REPL
cli-anything-krita基于 Click 构建,入口定义在 krita_cli.py。根命令是一个@click.group(invoke_without_command=True):
- 不给任何子命令直接运行时,自动进入交互式 REPL;
- 给出子命令时,作为一次性 one-shot 命令执行;
- 所有命令均可通过
--project/-p指定 Project JSON 路径,省略时使用会话内已加载的项目(REPL 内通过project new/open建立)。
一次性命令示例
# 创建新项目 cli-anything-krita project new -n "My Painting" -w 2048 -h 2048 -o project.json # 添加图层 cli-anything-krita --project project.json layer add "Sketch" -t paintlayer cli-anything-krita --project project.json layer add "Colors" -t paintlayer --opacity 200 cli-anything-krita --project project.json layer add "Background" -t paintlayer # 应用滤镜 cli-anything-krita --project project.json filter apply blur -l "Background" # 导出 PNG cli-anything-krita --project project.json export render output.png -p png --overwrite # JSON 输出模式(面向 AI Agent) cli-anything-krita --json --project project.json project info cli-anything-krita --json --project project.json layer list值得注意的细节:当以--project指定文件并执行 one-shot 命令时,CLI 会在命令结束时把改动自动回写(auto-save)到该 JSON 文件。这一逻辑实现在 krita_cli.py:根命令通过ctx.call_on_close注册回调,仅当"非 dry-run 且存在被调用子命令"时才保存,配合--dry-run标志可做"演练不落盘"。
交互式 REPL
# 直接启动 REPL(不给子命令时的默认行为) cli-anything-krita # 携带项目启动 cli-anything-krita --project project.jsonREPL 基于prompt-toolkit实现(repl_skin.py 提供提示符皮肤、横幅与命令补全)。在 REPL 中,输入的行会按空格切分后再次派发给同一个 Click CLI(krita_cli.py),因此 REPL 语法与一次性命令完全一致。REPL 会跟踪当前项目与modified状态(由会话 undo 能力判断),支持help查看可用命令列表、quit/exit/q退出。
命令组全景
README 用下表概括了全部命令组,结合源码可进一步细化每个子命令的参数行为:
| 命令组 | 子命令 | 作用 |
|---|---|---|
project | new、open、save、info | 项目管理 |
layer | add、remove、list、set | 图层栈管理 |
filter | apply、list | 滤镜与效果 |
canvas | resize、info | 画布属性 |
export | render、animation、presets、formats | 导出与渲染 |
session | undo、redo、history | 撤销/重做状态 |
status | — | 当前状态总览 |
全局选项与输出
--json:机器可读输出。普通模式逐行打印key: value,JSON 模式下输出json.dumps(data, indent=2);--dry-run:只执行不落盘(关闭自动保存);- 统一错误处理:所有命令通过
@handle_error装饰器包装(krita_cli.py),对FileNotFoundError、FileExistsError、RuntimeError及兜底异常在 JSON 模式下输出{"error": ..., "type": ...}结构,普通模式输出Error: ...到 stderr 并以退出码 1 结束——这为 Agent 解析失败原因提供了稳定的机器可读格式。
Project JSON:整个系统的状态中枢
项目数据结构
project new会生成符合PROJECT_VERSION = "1.0.0"的项目对象(见 project.py 的create_project)。其顶层结构为:
{ "name": "My Painting", "version": "1.0.0", "created": "<ISO-8601 UTC>", "modified": "<ISO-8601 UTC>", "canvas": { "width": 1920, "height": 1080, "colorspace": "RGBA", "depth": "U8", "resolution": 300, "profile": "sRGB-elle-V2-srgbtrc.icc" }, "layers": [ { "name": "Background", "type": "paintlayer", "opacity": 255, "visible": true, "blending_mode": "normal", "locked": false, "filters": [] } ], "metadata": { "author": "", "description": "", "tags": [] } }新建项目默认携带一个名为Background的 paintlayer。
合法取值约束(源码级校验)
project.py 定义了严格的枚举与校验规则,任何非法值都会抛出带提示的ValueError:
- 图层类型
VALID_LAYER_TYPES:paintlayer、grouplayer、vectorlayer、filterlayer、filllayer、clonelayer、filelayer; - 滤镜白名单
VALID_FILTERS:blur、gaussian-blur、motion-blur、lens-blur、sharpen、unsharp-mask、brightness-contrast、levels、curves、hue-saturation、color-balance、desaturate、invert、posterize、threshold、auto-contrast、normalize、emboss、edge-detection、oil-paint、pixelize、noise-reduction、halftone; - 色彩空间
VALID_COLORSPACES:RGBA、RGB、GRAYA、GRAY、CMYKA、CMYK; - 位深
VALID_DEPTHS:U8、U16、F16、F32。
CLI 层的project new支持--colorspace(默认RGBA)、--depth(默认U8)、--resolution(默认 300 DPI)。需注意 CLI 帮助中列出的色彩空间/位深与核心层校验集合略有差异(CLI 帮助文本列出CMYKA/LABA/XYZA与U8/U16/F16/F32),实际约束以 project.py 为准。
持久化与原子写入
open_project做基本完整性检查(必须含version与canvas键,否则判定为非法项目文件)。save_project在未指定路径时默认写为<项目名(空格转下划线)>.krita.json。写入使用 io.py 中的locked_save_json:在 Unix 上通过fcntl.flock(LOCK_EX)加排他锁后先截断再写入,保证并发/多进程访问下 JSON 不损坏;Windows 无fcntl时静默回退到普通写入。
各命令组实操详解
1.project项目管理
# 建项目:可自定义名称、宽高、色彩空间、位深、DPI,-o 指定 JSON 落盘位置 cli-anything-krita project new -n "My Painting" -w 2048 -h 2048 -o project.json cli-anything-krita project new -w 1920 -h 1080 --colorspace CMYKA --depth U16 --resolution 150 -o print.json # 打开既有项目 cli-anything-krita project open project.json # 保存(不指定 -o 时写回原路径) cli-anything-krita --project project.json project save cli-anything-krita --project project.json project save -o copy.json # 查看项目摘要(画布、图层数、每层属性、metadata) cli-anything-krita --project project.json project infoproject info内部调用 project.py 的project_info,返回轻量摘要,包括逐图层的visible、opacity、blending_mode与filter_count。
2.layer图层栈管理
# 添加图层:-t 指定类型(默认 paintlayer),--opacity 0-255,--hidden 创建即隐藏 cli-anything-krita --project project.json layer add "Sketch" -t paintlayer cli-anything-krita --project project.json layer add "Colors" -t paintlayer --opacity 200 cli-anything-krita --project project.json layer add "Group" -t grouplayer cli-anything-krita --project project.json layer add "Vector" -t vectorlayer --hidden # 移除图层 cli-anything-krita --project project.json layer remove "Sketch" # 列出图层(普通模式按 [索引] 名称 (类型) opacity=.. visible/hidden 打印) cli-anything-krita --project project.json layer list # 修改图层属性:支持 opacity / visible / blending_mode / locked / name / type cli-anything-krita --project project.json layer set "Colors" opacity 180 cli-anything-krita --project project.json layer set "Colors" visible false cli-anything-krita --project project.json layer set "Colors" blending_mode multiply底层实现要点(project.py):
- 图层名称必须唯一,重名抛
ValueError; opacity严格限定 0–255;layer set的 value 解析(krita_cli.py):true/yes→True,false/no→False,可解析为整数的转int,否则保留字符串,这让布尔与数值属性都能自然书写;- 移除不存在的图层抛
KeyError。
3.filter滤镜与效果
# 应用滤镜:-l 指定目标图层(省略时自动作用于图层栈最顶层),-c 传 JSON 配置 cli-anything-krita --project project.json filter apply blur -l "Background" cli-anything-krita --project project.json filter apply sharpen cli-anything-krita --project project.json filter apply levels -c '{"shadows": 10, "highlights": 240}' # 列出全部可用滤镜 cli-anything-krita --project project.json filter listfilter apply把滤镜条目追加到目标图层的filters数组({name, config}),config 缺省为空对象(project.py)。滤镜名必须是白名单内的合法标识。
4.canvas画布属性
# 只改传入的参数,其余保持不变 cli-anything-krita --project project.json canvas resize -w 4096 -h 4096 cli-anything-krita --project project.json canvas resize --resolution 600 # 查看画布宽高、色彩空间、位深、分辨率、ICC profile cli-anything-krita --project project.json canvas infoset_canvas(project.py)采用"仅更新传入关键字"的策略,宽度/高度/分辨率必须为正整数,否则抛ValueError。
5.export导出与渲染
# 渲染单张图片 cli-anything-krita --project project.json export render output.png -p png --overwrite cli-anything-krita --project project.json export render output.jpg -p jpeg cli-anything-krita --project project.json export render output.psd -p psd # 导出动画帧序列到目录(帧默认命名为 frame.*,详见下方说明) cli-anything-krita --project project.json export animation ./frames/ -p png # 列出预设与格式 cli-anything-krita export presets cli-anything-krita export formats关键保护机制:export render默认在目标文件已存在时抛FileExistsError,需显式加--overwrite才允许覆盖。
导出预设表(比 README 更完整)
预设定义集中在 export.py 的EXPORT_PRESETS中,README 列出的 8 项之外,源码还包含jpeg-low、tiff-lzw、gif、bmp:
| 预设 | 扩展名 | 描述与关键选项 |
|---|---|---|
png | png | 全透明通道,压缩级别 6,alpha=true |
png-web | png | Web 优化:压缩 9、尽量索引化(indexed=true) |
jpeg | jpg | 质量 90 |
jpeg-web | jpg | 质量 75 |
jpeg-low | jpg | 质量 50(源码新增) |
tiff | tiff | 不压缩(compression=none) |
tiff-lzw | tiff | LZW 压缩(源码新增) |
psd | psd | Photoshop 兼容 |
pdf | 文档导出 | |
svg | svg | 矢量导出 |
webp | webp | 质量 85 |
gif | gif | 动画用(源码新增) |
bmp | bmp | 不压缩(源码新增) |
export formats返回去重后的扩展名集合;export presets返回name/extension/description三元组。注意:cli-anything-krita export render的-p/--preset参数使用click.Choice限定,只接受上述预定义名,不能随意写扩展名。
6.session撤销/重做与历史
cli-anything-krita session undo cli-anything-krita session redo cli-anything-krita session history会话层由 session.py 的Session类实现,底层机制为深拷贝快照栈:
- 每次破坏性操作(
project new/open、layer add/remove/set、filter apply、canvas resize)都会调用snapshot(project, label)记录带时间戳与标签的深拷贝快照; undo指针回退并返回快照;在撤销后追加新操作会丢弃当前指针之后的 redo 分支(类似编辑器的主流分支策略,测试test_session_branch_discards_redo专门覆盖);session history打印每条快照的index/timestamp/label,当前指针用>>>标记;- 会话还支持
save(path)/load(path)持久化整条快照链与指针,便于跨进程恢复现场。
status命令则汇总当前状态:是否加载项目、项目路径、历史大小、can_undo/can_redo,若已加载项目还输出画布摘要与图层数;同时调用get_version()探测本机 Krita 版本与安装情况——这对 Agent 检查运行环境非常有用。
工作流实例:从零开始的一张"绘画工程"
README 与技能文档(SKILL.md)给出了一条端到端流水线,这里结合 JSON 模式串联演示:
# 1. 建项目:3000x4000 竖幅插画画布 cli-anything-krita --json project new -n "Illustration" -w 3000 -h 4000 -o art.json # 2. 搭图层栈:由下至上 Background -> Sketch -> Inking -> Colors -> Effects cli-anything-krita --json -p art.json layer add "Background" -t paintlayer cli-anything-krita --json -p art.json layer add "Sketch" -t paintlayer --opacity 180 cli-anything-krita --json -p art.json layer add "Inking" -t paintlayer cli-anything-krita --json -p art.json layer add "Colors" -t paintlayer cli-anything-krita --json -p art.json layer add "Effects" -t paintlayer --opacity 128 # 3. 给底层图层施加模糊 cli-anything-krita --json -p art.json filter apply blur -l "Background" # 4. 导出最终成品(覆盖旧文件) cli-anything-krita --json -p art.json export render final.png -p png --overwrite每次命令的 JSON 输出都能被上游脚本/AI Agent 直接解析,形成"声明式作画 + 命令式驱动"的闭环。
底层原理:从 Project JSON 到成品像素
README 的 "How it works" 四步流水线在源码中体现为清晰的职责分层:
Step 1 & 2:构建.kra文件。export.py 的build_kra_from_project把一个 Project JSON 打包成 Krita 原生格式。.kra本质是 ZIP 归档,构建器保证如下布局:
mimetype:必须是第一个且不压缩的条目,内容为application/x-kra;maindoc.xml:由_build_maindoc_xml生成的 Calligra/Krita 命名空间 DOC 文档,声明图像名、宽高、colorspacename、x/y 分辨率,并把每个paintlayer写成<layer>节点(含visible、opacity、filename、可选uuid);documentinfo.xml:Dublin Core 元数据(标题、创建者、日期);<图像名>/layers/<图层安全文件名>:对每个 paint 图层写入一张由_make_blank_png手工构造的全透明 RGBA PNG(用标准 PNG chunk + zlib 逐扫描线压缩生成)。
Step 3:调用真实 Krita。krita_backend.py 的export_file组合出krita --export --export-filename <out> [--export-option key=value ...] <input.kra>子进程命令,其中--export-option由预设的 options(quality/compression/alpha 等)展开;默认 300 秒超时,并收集returncode/stdout/stderr归一化返回。export_animation则改用--export-sequence与可选的--export-sequence-start/--export-sequence-end输出帧序列。此外后端还提供run_script(把 Python 源码写入临时脚本后以krita --script执行)、create_new_image(用 Krita 内嵌 Python APIapp.createDocument(...)生成新画布)与batch_export等高级原语。
Step 4:输出校验。export_image在返回前会检查输出文件是否真实存在并统计file_size,最终返回{output_path, file_size, format, method},method 固定为"krita_backend",表明渲染确实发生在 Krita 引擎侧。
测试与验证:README 之外的工程质量
测试分两层(详见 tests/TEST.md):
- 单元层 test_core.py 覆盖 project(创建默认/自定义、往返存取、全部图层类型、移除失败、属性校验)、session(undo/redo 边界、分支丢弃 redo、持久化往返)、export(预设键完整性、
.kra内含 mimetype/maindoc.xml/documentinfo.xml)与后端(find_krita、get_version); - 端到端层 test_full_e2e.py 覆盖完整管线(建项目→加图层→产出
.kra)、真实 Krita 导出(PNG/JPEG)以及以子进程方式测试 CLI 命令本身(--help、project new、图层工作流、预设列举、status、全流程)。
测试结果文档记录:45 通过、2 跳过(真实导出测试在无显示服务器的 Windows 下跳过,Linux 配合 Xvfb 可运行),也印证了--export依赖图形/虚拟显示环境的客观限制。此外,工具链还内置一份面向 Agent 的技能文档 SKILL.md,把命令参考与 JSON 模式封装为可直接被智能体读取并调用的技能清单。
适用边界与建议
cli-anything-krita管理的是工程状态(Project JSON),.kra中每个 paint 图层默认是一张空(透明)画布;位图内容编辑、复杂笔刷等仍依赖在 GUI 中处理或用run_script注入 Krita 内嵌 Python 脚本完成;- 真实渲染需要本机存在可被发现的 Krita(可用
status命令快速探测),且无头环境下可能需要虚拟显示(如 Linux 的 Xvfb); - 面向 Agent/自动化时优先使用
--json,配合--dry-run可以先验证命令行为再落盘。
【免费下载链接】CLI-Anything"CLI-Anything: Making ALL Software Agent-Native" -- CLI-Hub: https://clianything.cc/项目地址: https://gitcode.com/GitHub_Trending/cl/CLI-Anything
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考