Files
AnyImage/docs/development.md
nan 6c8358f92f Refactor image processing and cutout functionalities
- Updated the naming convention for upscaled images to include underscores and file extensions.
- Renamed properties related to cutout pixel size to point spacing for clarity.
- Adjusted alpha region calculations to use a half-alpha threshold for better accuracy.
- Enhanced the handling of foreground mesh masks to consider half-alpha values.
- Introduced new functions for unbounded selections and cutout images, ensuring proper handling of source and selection images.
- Improved test coverage for cutout functionalities, including bounds mapping and alpha preservation.
- Updated tests to reflect changes in naming conventions and functionality adjustments.
2026-08-27 12:01:47 +08:00

7.3 KiB
Raw Blame History

程序设计、开发与许可证

程序设计

AnyImage 分为 Blender 交互层、BlendJob Runtime 和 Job Server 计算层。

flowchart LR
    UI["菜单 / Panel"] --> Operator["Feature Operator"]
    Operator --> Runtime["JobRuntime"]
    Runtime --> Job["Server Job"]
    Job --> Files["Job Directory"]
    Files --> Response["Operator Response"]
    Response --> Scene["Blender Scene"]

Blender 交互层管理 UI、RNA 状态、任务参数和结果导入。Runtime 管理 Environment、Server、队列、进度与取消。Server Job 组合媒体、模型、几何和输出模块。完整运行设计见 Job Server。

代码组织

位置 内容
__init__.py Blender 类型、菜单与 Runtime 注册
clipboard_image/ 剪贴板读取、上下文粘贴与快捷键
menu.py、panel.py 用户入口
preferences.py、properties.py 扩展配置与 Scene 状态
runtime.py JobRuntime 配置
operators/ Blender 功能与结果导入
server/jobs/ Server 工作流
server/models/ ONNX 模型适配
server/geometry/ 纯数据几何处理
server/outputs/ 文件序列化
server/media/ 媒体输入
assets/O_AnyImage.blend Geometry Nodes 与材质资产

Mesh Plane、Depth Plane、Surface、Background 和 Balloon 按功能组织。一个功能的入口、请求和 Blender 回写放在一起;跨功能的图片、材质和参数处理放在 operators/common.py、operators/image.py 与 operators/material.py。

Server 的模型模块返回 Prediction,几何模块处理数组与网格,输出模块写文件。Blender 数据只在 Operator Response 的主线程阶段创建。Cutout 与 Balloon 在未启用 Refine 和 Normal 时不提交 Job:Operator 直接在内存中合成最终 Alpha,并调用 server/geometry/cutout.py 的纯数据轮廓函数后创建网格。Refine、Normal 与 Depth Job 只返回最终图片 Alpha 和被选中的 AI 数组或纹理;normal_analysis 为假时不请求 MoGe-2 normal 模型,也不写入 normal.png。外轮廓、孔洞及基础面始终在 Blender 主线程生成,不使用 contour.json 作为中间结果。Cutout 的 Point Spacing 由完整源图尺寸换算到平面空间;裁切 bounds 只参与轮廓坐标、局部平面和 UV 映射。

扩展级设置统一通过 preferences.addon_preferences() 读取,不归属 BlendJob Runtime;Storage Root 路径回调也由 Preferences 模块提供,Runtime 只消费回调结果。扩展包标识直接使用根模块中的 __package__,以兼容 Blender 实际的 bl_ext.<repository>.anyimage 命名空间;不得按第一个点截断,否则会错误查找 bl_ext 并静默回退默认值。Preferences 的设备枚举和面板数据按需导入,避免循环依赖。

正式 Upscale 使用仅具备 UNDO 的 Job Operator 完成输入准备、任务提交和结果回写,不注册 Last Operation 重做面板。每次 execute() 都从 Preferences 读取默认模型与输出长边上限,再写入隐藏的可序列化 Operator 参数。高清结果只通过 Image.anyimage_upscale_source 保存原始 Image 引用;Operator 自身仅以隐藏的 StringProperty 保存原图名称,并在主线程响应时从 bpy.data.images 重新解析,避免保留已被移除的 RNA 指针。再次执行时从原图引用准备输入并替换当前高清数据块;无其他用户的旧高清结果会在新结果配置成功后移除,因此同一 Empty 只保留一个高清版本。模型只处理 RGB;源图 Alpha 经过同样的输入尺寸限制后独立放大并合并回结果。

Blender 侧需要落盘的 Packed Image 与浮点深度 EXR 都通过 Image.save(save_copy=True) 导出,不调用 save_render,避免把 Scene Render 的 View Transform、Look 或 Exposure 耦合到模型输入和 Non-Color 数据;颜色结果载入后继承源 Image 的 Color Space。Server 中的 PIL.Image.save() 只负责普通文件编码,不属于 Blender Render 色彩管理。

Image Box、Lasso、Line、Polyline 与 Perspective 位于 operators/image_edit/ 功能包。模块职责、交互状态、像素管线、Refine 和 Empty 定位见 Image 工具技术实现。

项目结构

.
├── README.md
├── docs/
├── pack.py
├── sync_models.py
├── src/anyimage/
│   ├── blender_manifest.toml
│   ├── runtime.py
│   ├── menu.py
│   ├── panel.py
│   ├── preferences.py
│   ├── properties.py
│   ├── clipboard_image/
│   ├── operators/
│   ├── server/
│   ├── assets/
│   └── wheels/
├── tests/
└── tools/

开发命令

在项目根目录使用 Git Bash:

uv sync
uv run pytest
uv run pytest tests/test_addon.py tests/test_manifest.py tests/test_pack.py -v
uv run python pack.py

pack.py 为 Windows x64、macOS Apple Silicon 与 Linux x64 构建扩展 ZIP 到 dist/。下载项目依赖时会把 src/anyimage/wheels/ 作为优先可用的 wheel 来源,因此尚未发布到 PyPI 的本地 BlendJob 构建也能进入三个平台包。依赖、wheel 或 Manifest 改变后,应同步检查 pyproject.toml、uv.lock、blender_manifest.toml 与打包测试。

CI 分为三条流程:

  • test.yml:在 push、Pull Request 与手动触发时运行测试
  • build.yml:响应 v* tag,测试后构建并上传 Release
  • docs.yml:文档变化后构建并部署站点

文档

本地预览和严格构建:

uv run --only-group docs mkdocs serve
uv run --only-group docs mkdocs build

版本化发布可使用 Mike:

uv run --only-group docs mike deploy <version> -p
uv run --only-group docs mike set-default <version> -p

自动部署将 MkDocs 站点发布到专用 Cloudflare Worker。仓库需要配置 CLOUDFLARE_ACCOUNT_ID、CLOUDFLARE_API_TOKEN 和 CLOUDFLARE_WORKER_NAME。Worker 路由对应 docs.omoolab.xyz/anyimage/*。

资产构建与验证

tools/ 中的资产脚本依赖 bpy,应由 Blender 执行:

BLENDER_BIN="/c/Program Files/Blender Foundation/Blender 4.5/blender.exe"

"$BLENDER_BIN" --background --python tools/build_geometry_nodes_asset.py
"$BLENDER_BIN" --background --python tools/validate_depth_plane_asset.py
"$BLENDER_BIN" --background --python tools/validate_mesh_plane_asset.py
"$BLENDER_BIN" --background --python tools/validate_geometry_nodes_asset.py
"$BLENDER_BIN" --background --python tools/validate_balloon_asset.py
"$BLENDER_BIN" --background --python tools/validate_moge_depth_plane.py
"$BLENDER_BIN" --background --python tools/validate_moge_surface.py

修改节点组、材质组或资产接口后,运行对应验证脚本和完整测试。Python、文档或打包逻辑变化无需重建 .blend 资产。

上游与许可证

  • Depth Anything 3 代码采用 Apache 2.0
  • BEN2 ONNX 模型采用其仓库声明的 Apache 2.0 License
  • Real-ESRGAN General WDN x4v3 与 Real-ESRGAN x4plus ONNX 权重采用其模型仓库声明的 BSD 3-Clause License
  • SAFMN Real x4 ONNX 权重采用其模型仓库声明的 Apache 2.0 License
  • 模型目录显式声明可用的 Hugging Face 仓库;未声明时只同步经过大小与 SHA-256 校验的 R2 制品
  • AnyImage Extension 代码采用 GPL-3.0-or-later
  • 模型权重许可证由所选 Hugging Face 模型仓库决定