# Image 工具技术实现 Image Box、Lasso 与 Perspective 位于 `operators/image_extract/`。三者共享源图选择、设置、图片写回、空间定位、Continuous 分层和可选背景清理。 ## 模块职责 ```mermaid flowchart LR Box["box.py\nWorkspaceTool"] --> Region["region.py\nBox / Lasso Operator"] Lasso["lasso.py\nWorkspaceTool"] --> Region Perspective["perspective.py\n四点与透视矫正"] Region --> Common["common.py\n共享选择、设置与结果写回"] Perspective --> Common Common --> Job["extract-image-background\n可选 BEN2 Job"] ``` `box.py` 与 `lasso.py` 只声明 WorkspaceTool。两者通过 `selection_shape` 复用 `ExtractImageRegion`;Perspective 保留独立 Operator,因为它还有四点输入、比例预览和 Homography。 ## 首次点击 `resolve_image_extract_click()` 将首次点击归为两种结果: | 点击目标 | 结果 | | --- | --- | | 另一张 Image Empty | 只选择并设为 Active | | 当前 Active 图片、空白或非图片对象 | 使用当前 Active 图片开始取区 | 这段逻辑由三个工具共用。点击非图片对象后会恢复原选择,避免触发对象移动或更换源图。 ## 处理管线 ```mermaid flowchart TD Input["屏幕选区"] --> Pixels["转换到源图片像素坐标"] Pixels --> Background{"Remove Background?"} Background -- 否 --> Local["Blender 内处理 RGBA"] Background -- 是 --> Server["选区画布 → BEN2 → 局部图片"] Local --> Tool{"工具类型"} Server --> Tool Tool -- Box / Lasso --> Crop["Alpha bounds + Padding"] Tool -- Perspective --> Warp["预乘 Alpha Homography"] Warp --> Crop Crop --> Result["创建并 Pack Image\n定位 Empty"] ``` Box 与 Lasso 将选区外 RGBA 清为透明黑,再按非零 Alpha 的最小范围裁切。Perspective 先将四点规范为沿源图 X/Y 方向的凸四边形,再按确认的宽高比重采样;点击顺序不参与输出旋转。 透视预览固定生成一次 512 × 512 临时 Image。鼠标移动只改变屏幕上的预览比例;确认后才执行全分辨率重采样。 ## 背景清理 `extract-image-background` 与标准 `remove-background` Job 共用 `remove_image_background()`。图片工具的 Job 只增加三项选区语义: - polygon mask; - 局部图片在源图中的 bounds; - Box / Lasso 使用的透明 Padding。 Perspective 请求的 Job Padding 固定为 0。局部结果回到 Blender 后先换算为源图坐标,再执行透视矫正和最终 Padding。 ## Empty 定位与 Continuous Box 与 Lasso 根据裁切前后的像素 bounds 换算 Empty 的中心和显示尺寸。Perspective 使用源四边形的轴对齐 bounds 近似放置结果。三者都沿用源 Empty 的矩阵,因此朝向与深度不变。 Continuous 关闭时直接更新源 Empty;开启时复制对象,并沿操作开始时捕获的 View 方向偏移: ```text offset = display_size × world_scale × 0.001 × layer ``` `layer` 记录在源对象的 `_anyimage_extract_layer` Custom Property 中,使连续结果依次靠近当前 View。 ## 维护约束 - WorkspaceTool 的显示设置放在 `box.py`、`lasso.py`、`perspective.py`。 - Box / Lasso 的共享交互放在 `region.py`,跨三个工具的行为放在 `common.py`。 - Blender 数据只在主线程 Operator 中读写;Server 参数保持为可序列化字典。 - 普通裁切不启动 Job Server;只有 Remove Background 需要 Environment 与 BEN2。