Files
AnyImage/docs/image-tools-technical.md
nan 1613bd3194 Add image perspective editing and related tools
- Implemented the Image Perspective tool for editing image corners in Blender.
- Created a new operator `EditImagePerspective` to handle the perspective transformation.
- Added a preview feature for the perspective adjustment.
- Introduced the `ImagePolylineTool` for editing image masks with polylines.
- Developed backend support for Real-ESRGAN model inference, including ONNX integration.
- Added functionality for image masking and background removal.
- Created unit tests for the Real-ESRGAN ONNX model to ensure correct preprocessing and inference.
2026-08-22 22:17:10 +08:00

4.5 KiB
Raw Blame History

Image 工具技术实现

Image 工具位于 operators/image_edit/。Box、Lasso、Line 与 Polyline 共享直接编辑管线;Perspective 在工具栏中独立显示并处理 Homography,但复用源图选择、绘制和 Empty 写回。

模块职责

flowchart LR
    Tools["box / lasso / line / polyline\nWorkspaceTool"] --> Mask["mask.py\n手势、Refine、Invert"]
    Perspective["perspective.py\n四点、比例、Homography"]
    Mask --> Common["common.py\n选择、绘制、裁切、Empty 写回"]
    Perspective --> Common
    Mask --> Job["refine-image-mask\nBEN2 内容 mask"]
  • box.py、lasso.py、line.py、polyline.py 只声明 WorkspaceTool。
  • mask.py 用 EditImageMask 统一四种手势;RefineImageMask 负责异步 BEN2 响应。
  • perspective.py 维护四点输入、比例预览和全分辨率重采样。
  • common.py 只放跨两条管线实际共用的逻辑。

首次点击

resolve_image_edit_click() 临时调用 Viewport Select 判断点击目标:

点击目标 行为
另一张 Image Empty 选择并设为 Active,本次不编辑
当前 Active 图片、空白或非图片对象 恢复原选择并开始编辑当前图片

这避免工具在无有效源图时退化为对象移动,也让用户无需切回 Select Tool。

Mask 管线

flowchart TD
    Gesture["屏幕手势"] --> Polygon["源图片像素 polygon / mask"]
    Polygon --> Refine{"Refine Selection?"}
    Refine -- 否 --> Content["几何 mask"]
    Refine -- 是 --> Server["选区外 RGBA 清零 → BEN2"]
    Server --> Content2["BEN2 Alpha × 几何 mask"]
    Content --> Invert{"Invert?"}
    Content2 --> Invert
    Invert -- 否 --> Final["final mask"]
    Invert -- 是 --> Reverse["1 - final mask"]
    Final --> Apply["源 Alpha × mask"]
    Reverse --> Apply
    Apply --> Crop["按非零 Alpha 紧裁切\n保留源 RGB"]
    Crop --> Write["替换 Image 并更新 Empty 显示"]

Box / Lasso 的顺序固定为 Refine → Invert。BEN2 只提供内容 Alpha;最终 RGB 始终来自源图。Blender 侧只修改 Alpha,不清理透明区 RGB,以避免 Viewport 纹理过滤产生黑边。Line / Polyline 强制关闭 Refine,只执行几何 mask 与 Invert。

Line 的屏幕坐标 Y 轴与图片坐标 Y 轴方向相反,因此像素阶段会反转线段端点,使半透明预览侧与实际保留侧一致;Ctrl 只影响屏幕端点的 5° 吸附。零长度点击在投影前直接取消,投影结果不足两个点时也会安全终止。Polyline 接近起点时绘制闭合圆环,并支持单击起点或 Enter 完成;完成时显式闭合,不把当前游标位置作为额外顶点。

Perspective 管线

四点先按源图片 X/Y 方向规范为凸四边形,输入顺序不参与输出方向。第四点后只生成一次 512 × 512 临时纹理;移动鼠标改变 UI 比例,确认时才进行全分辨率 Homography。

透视重采样使用预乘 Alpha 插值,随后恢复 RGB、清理透明像素并紧裁切。输出最长边限制为 8192 px,总像素限制约 16 MP。

Perspective 不调用 BEN2,也不支持 Invert。它是 deform 工具,不属于 mask 清理语义。

Empty 写回

replace_empty_image_pixels() 创建并 Pack 新 Image datablock,然后替换当前 Empty 的 data。它不复制对象,也不修改 matrix_world。

align_empty_display_to_bounds() 根据源画布、旧 plane_bounds、结果尺寸和放置 bounds 更新:

  • empty_display_size;
  • empty_image_offset。

Box、Lasso、Line 与 Polyline 的放置 bounds 等于最终裁切范围,因此像素与原图片平面严格对齐。Perspective 的结果比例可能不同于四边形轴对齐范围,因此只保持中心和覆盖尺度近似一致。

Server 边界

普通 Mask 和 Perspective 完全在 Blender 侧执行。只有 Box / Lasso 的 Refine Selection 提交 refine-image-mask:

  1. 根据 polygon 创建局部透明画布;
  2. 清空选区外 RGBA;BEN2 公共入口再以输入 Alpha 遮住透明 RGB;
  3. 使用共享的 remove_image_background() 运行 BEN2;
  4. 再乘几何 selection mask;
  5. 返回紧裁切的 image.png 与源图坐标 bounds.json。

Blender 只读取返回图片的 Alpha,并把它应用到原图 RGB。相同的 BEN2 输入清理规则也用于 Remove Background、Depth Plane、Surface 和 Balloon;正式输出使用源 RGB 与 BEN2 Alpha。Blender 数据只在主线程 Operator 中读写,Job 参数保持为可序列化字典。