Files
AnyImage/openspec/changes/replace-crop-with-mask-and-rectify/specs/image-edit-tools/spec.md
nan 1994d38ccd Add comprehensive tests for image processing and mask functionalities
- Introduced tests for color image handling, ensuring source preservation and premultiplied alpha usage.
- Implemented tests for brush stroke operations, validating segment boundaries and brush anti-aliasing.
- Added tests for frame anti-aliasing, confirming correct rendering behavior with various alpha values and depth settings.
- Created tests for frame projection, ensuring accurate overlap calculations and half-plane clipping.
- Developed tests for image premultiplied retention, verifying behavior during loading and packing processes.
- Added undo functionality tests for mask operations, ensuring single transaction behavior during edits.
2026-09-05 21:33:11 +08:00

7.4 KiB
Raw Blame History

ADDED Requirements

Requirement: Image Edit group uses Frame Mask and Rectify

系统 SHALL 将图片编辑工具组依次注册为 Frame、Mask 和 Rectify,并 SHALL 将 Cutout 作为其后的独立工具。系统 MUST NOT 注册旧 Crop Lasso、Crop Polyline 或 Crop Perspective Tool ID,也 MUST NOT 提供旧 ID 的兼容入口。

Scenario: Image Edit tools are registered

  • WHEN AnyImage 扩展完成注册
  • THEN 3D Viewport 图片编辑工具组按 Frame、Mask、Rectify 顺序显示,Cutout 紧随其后

Scenario: Legacy Crop tools are absent

  • WHEN 系统枚举已注册的 AnyImage WorkspaceTool 和 Operator
  • THEN 不存在 Crop Lasso、Crop Polyline、Crop Perspective 或其旧 ID

Requirement: Mask combines Lasso and Brush gestures

Mask SHALL 是一个 WorkSpaceTool 和一个图片 Alpha 编辑 Operator,并 SHALL 提供 LASSO 与 BRUSH Gesture。两种 Gesture MUST 生成相同的 SelectionMask 产物并进入相同的 Alpha 合成入口。

Scenario: Lasso edits Alpha

  • WHEN 用户在 Mask 中选择 Lasso 并完成一个有效闭合手势
  • THEN 系统将该 Lasso 栅格化一次并按当前 Mode 编辑 active Image Empty 的 Alpha

Scenario: Brush edits Alpha

  • WHEN 用户在 Mask 中选择 Brush 并完成一次点击或拖动
  • THEN 系统将连续圆形笔画栅格化一次并按当前 Mode 编辑 active Image Empty 的 Alpha

Requirement: Mask provides three Alpha modes

Mask SHALL 提供 SET、ADD、SUBTRACT 三种互斥 Mode,并 SHALL 在 Tool Settings 中使用 Set、Add、Subtract 图标展开显示。设当前 Alpha 为 A、本次 SelectionMask 权重为 M,系统 MUST 分别计算 A × M、max(A, M)、A × (1 - M),同时保持 RGB 不变。

Scenario: Set keeps only current content inside the gesture

  • WHEN 用户以 Set 应用一次 Mask 手势
  • THEN 手势外 Alpha 变为零,手势内 Alpha 等于当前 Alpha 与 SelectionMask 权重的乘积

Scenario: Add extends current Alpha

  • WHEN 用户以 Add 应用一次 Mask 手势
  • THEN 每个像素 Alpha 等于当前 Alpha 与 SelectionMask 权重的较大值

Scenario: Subtract removes current Alpha

  • WHEN 用户以 Subtract 应用一次 Mask 手势
  • THEN 每个像素 Alpha 等于当前 Alpha 与 SelectionMask 补集的乘积

Scenario: Fractional edge coverage is preserved

  • WHEN SelectionMask 边缘包含 0 与 1 之间的权重
  • THEN 系统使用该权重执行对应公式而不是先转为布尔值

Requirement: Mask settings persist per scene

系统 SHALL 在 Scene 中保存 Mask 的 Gesture、Mode 和 Radius。Radius SHALL 是正整数 Region 屏幕像素,默认 25 px,并 MUST 仅在 Gesture 为 Brush 时显示和生效;每次手势开始后 MUST 冻结本次使用的设置。

Scenario: Mask settings are reused

  • WHEN 用户设置 Brush、Add 和一个 Radius 后完成一次操作并再次使用 Mask
  • THEN Tool Settings 保持 Brush、Add 和该 Radius

Scenario: Lasso hides Radius

  • WHEN Mask Gesture 为 Lasso
  • THEN Tool Settings 不显示 Radius 且 Lasso 栅格化不读取 Radius

Requirement: Brush produces continuous screen-space coverage

Brush SHALL 以当前 Region 中的屏幕像素显示 Radius 圆环,并 MUST 让单击产生圆形覆盖、拖动产生带圆角端点的连续覆盖。快速移动时相邻事件点之间 MUST NOT 留下未覆盖间隙,图片范围外的笔画 MUST 被裁到图片画布。

Scenario: Single click stamps a circle

  • WHEN 用户以 Brush 在图片上单击而不拖动
  • THEN 系统以点击位置和当前 Radius 生成一个圆形 SelectionMask

Scenario: Sparse motion events remain connected

  • WHEN 一次 Brush 拖动的相邻采样点距离大于 Radius
  • THEN 两点之间仍由连续笔画覆盖

Scenario: Viewport scale does not change displayed Radius

  • WHEN 用户改变 Viewport 缩放后以同一 Radius 使用 Brush
  • THEN 笔刷圆环在 Region 中继续使用相同屏幕像素半径

Requirement: Mask preserves the rectangular image canvas

Mask SHALL 创建与当前图片相同宽高的 packed Image,并 SHALL 保持 active Image Empty 的对象身份、matrix、display size 和 image offset。Mask MUST NOT 按 Alpha 紧裁切或传入 placement bounds,且 SHALL 允许产生全透明结果。

Scenario: Lasso keeps the canvas

  • WHEN Lasso 手势只覆盖图片的一小部分
  • THEN 结果图片尺寸和 Image Empty 矩形画框与操作前完全相同

Scenario: Brush keeps the canvas

  • WHEN Brush 手势只覆盖图片的一小部分
  • THEN 结果图片尺寸和 Image Empty 矩形画框与操作前完全相同

Scenario: Entire Alpha can be removed

  • WHEN Subtract 覆盖当前全部非零 Alpha
  • THEN 操作成功并产生相同尺寸的全透明结果

Scenario: Shared source remains unchanged

  • WHEN active Image Empty 与其他对象共享同一个源 Image
  • THEN active 对象改为引用新的编辑结果,其他对象继续引用未修改的源 Image

Requirement: Mask and Rectify replace the active image

Mask 与 Rectify SHALL 直接替换 active Image Empty 承载的 Image,并 MUST NOT 提供 Keep Original 属性、Operator 参数或复制结果对象的路径。Frame SHALL 继续让 active Image Empty 承载合成结果。

Scenario: Mask replaces the active result

  • WHEN 用户完成一次 Mask 操作
  • THEN active Image Empty 本身承载结果且系统不创建其副本

Scenario: Rectify replaces the active result

  • WHEN 用户完成一次 Rectify 操作
  • THEN active Image Empty 本身承载结果且系统不创建其副本

Requirement: Rectify performs four-point perspective correction

Rectify SHALL 接受四个图片点,规范化为有效凸 Quad,并通过 Homography 生成目标宽高比的矩形图片。系统 SHALL 保留现有预览、输出分辨率限制、可见 Alpha trim 和结果 placement 语义,同时 SHALL 在类名、Tool/Operator ID、标签、状态、warning 与 Undo 中统一使用 Rectify 术语。

Scenario: Four points create a rectified image

  • WHEN 用户为 still Image Empty 提交四个构成有效凸 Quad 的点
  • THEN 系统生成透视校正后的矩形图片并替换 active Image Empty 的 Image

Scenario: Rectify retains output limits

  • WHEN 四点区域对应的原始输出超过长边或总像素限制
  • THEN 系统按既有 Rectify 输出限制等比约束结果

Requirement: Refine Selection is absent from Mask and Cutout

Mask 与 Cutout MUST NOT 声明、显示、保存或传递 Refine Selection。Server MUST NOT 注册 refine-image-selection Job,Cutout Job MUST NOT 接收或执行 refine_selection 与 refine_model;BEN2 Remove Background 与 Debug 能力 SHALL 保持可用。

Scenario: Mask has no AI refinement

  • WHEN 用户查看 Mask Tool Settings 或执行 Mask
  • THEN 不存在 Refine Selection 选项、AI readiness 门控或 BEN2 Job

Scenario: Cutout runs without refinement parameters

  • WHEN 用户创建本地、Depth 或 Normal Cutout
  • THEN Blender 和 Server 请求中不包含 Refine Selection 参数,最终 Shape 仍由本地几何 SelectionMask 约束

Scenario: BEN2 remains available elsewhere

  • WHEN 用户运行 Remove Background 或 BEN2 Debug
  • THEN 系统继续使用现有 BEN2 模型与缓存完成请求