docs: align Markdown table columns in README

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
a1518 2026-07-01 00:53:21 -07:00
parent db572ee51d
commit 1b3a6d5a4a

View File

@ -107,6 +107,7 @@ import '@shopify/react-native-skia';
**几乎总是**因为 Metro 同时解析到多份 reanimated / skia / gesture-handler / fast-opencv / safe-area 等包。 **几乎总是**因为 Metro 同时解析到多份 reanimated / skia / gesture-handler / fast-opencv / safe-area 等包。
**最佳实践** **最佳实践**
- 直接复制 `example/metro.config.js` 里的 `singletonPackages` + extraNodeModules + blockList 写法 - 直接复制 `example/metro.config.js` 里的 `singletonPackages` + extraNodeModules + blockList 写法
- 在你的 `index.js` 最顶部加入 gesture-handler → reanimated → skia 三个 import - 在你的 `index.js` 最顶部加入 gesture-handler → reanimated → skia 三个 import
- 重启 Metro (`--reset-cache`) + 重装 app - 重启 Metro (`--reset-cache`) + 重装 app
@ -141,8 +142,9 @@ import MaskSegmentCanvas, {
主要导出一览: 主要导出一览:
| 类别 | 名称 | | 类别 | 名称 |
| ---- | ---- | | -------------- | ----------------------------------------------------------------------------------- |
| 组件 | `MaskSegmentCanvas`default | | 组件 | `MaskSegmentCanvas`default |
| Ref / Props 类型 | `MaskSegmentCanvasRef`、`MaskSegmentCanvasProps` | | Ref / Props 类型 | `MaskSegmentCanvasRef`、`MaskSegmentCanvasProps` |
| 会话 / 回调类型 | `MaskSegmentSession`、`PaintCallbackPayload`、`PaintedRegionRecord`、`SavePaintResult` | | 会话 / 回调类型 | `MaskSegmentSession`、`PaintCallbackPayload`、`PaintedRegionRecord`、`SavePaintResult` |
@ -152,6 +154,7 @@ import MaskSegmentCanvas, {
| 工具 | `prewarmPngBgrCacheAsync`、`prewarmPngBgrCache` | | 工具 | `prewarmPngBgrCacheAsync`、`prewarmPngBgrCache` |
| 运行时 | `DEFAULT_*_CONFIG`、`getMaskSegmentRuntimeConfig`、`setMaskSegmentRuntimeConfig` | | 运行时 | `DEFAULT_*_CONFIG`、`getMaskSegmentRuntimeConfig`、`setMaskSegmentRuntimeConfig` |
--- ---
## 推荐:通过 example/ 目录学习集成 ## 推荐:通过 example/ 目录学习集成
@ -385,15 +388,15 @@ export function PaintScreen() {
| state | 类型 | 用途 | | state | 类型 | 用途 |
| ------------------ | -------------------------- | ---- | | ----------------- | ---------------------------- | ------------------------------------------------ |
| `imagePaths` | `{ origin, mask } \| null` | 业务侧解析后的本地/远程图片路径 | | `imagePaths` | `{ origin, mask } | null` | 业务侧解析后的本地/远程图片路径 |
| `pathsError` | `string` | 路径解析或 PNG 预热失败文案 | | `pathsError` | `string` | 路径解析或 PNG 预热失败文案 |
| `watchState` | `MaskSegmentWatchState \| ''` | `onWatch` 上报的初始化阶段 | | `watchState` | `MaskSegmentWatchState | ''` | `onWatch` 上报的初始化阶段 |
| `isInteractive` | 派生 | `interactive``mask_paths_ready` 时为 true可开放操作 | | `isInteractive` | 派生 | `interactive``mask_paths_ready` 时为 true可开放操作 |
| `isOutlineReady` | 派生 | `mask_paths_ready` 时为 true轮播虚线已就绪 | | `isOutlineReady` | 派生 | `mask_paths_ready` 时为 true轮播虚线已就绪 |
| `isCanvasLoading` | 派生 | 画布初始化阻塞 Loading不含 PNG 路径等待) | | `isCanvasLoading` | 派生 | 画布初始化阻塞 Loading不含 PNG 路径等待) |
| `errorMessage` | `string` | 由 `onError` 写入的分割/加载失败文案 | | `errorMessage` | `string` | 由 `onError` 写入的分割/加载失败文案 |
| `sessionDraft` | `MaskSegmentSession \| null` | MMKV 等恢复的草稿 | | `sessionDraft` | `MaskSegmentSession | null` | MMKV 等恢复的草稿 |
#### 配置项怎么选 #### 配置项怎么选
@ -447,8 +450,9 @@ const hasError = watchState === 'error';
### 图片与初始化 ### 图片与初始化
| 属性 | 类型 | 必填 | 默认 | 说明 | | 属性 | 类型 | 必填 | 默认 | 说明 |
| ---- | ---- | ---- | ---- | ---- | | ------------------------ | ------------------------- | --- | --- | ----------------------------------------------------------------- |
| `originUrl` | `string` | 是* | — | 原图地址(`file://`、绝对路径或 `http(s)://` | | `originUrl` | `string` | 是* | — | 原图地址(`file://`、绝对路径或 `http(s)://` |
| `maskUrl` | `string` | 是* | — | 掩码图地址(语义色块图,建议与原图同尺寸) | | `maskUrl` | `string` | 是* | — | 掩码图地址(语义色块图,建议与原图同尺寸) |
| `originImgPath` | `string` | — | — | **deprecated**,请用 `originUrl` | | `originImgPath` | `string` | — | — | **deprecated**,请用 `originUrl` |
@ -457,13 +461,16 @@ const hasError = watchState === 'error';
| `initialPaintColor` | `BgrColor` | 否 | — | **可选**。初始自定义笔刷色 `{ b, g, r }`;不传则默认无笔刷,需用户选色或 `ref.setPaintColor` | | `initialPaintColor` | `BgrColor` | 否 | — | **可选**。初始自定义笔刷色 `{ b, g, r }`;不传则默认无笔刷,需用户选色或 `ref.setPaintColor` |
| `initialPaintConfigJson` | `Record<string, unknown>` | 否 | — | **可选**。与 `initialPaintColor` 配套的笔刷配置,上色成功时随 `onPaintCallback` 回传 | | `initialPaintConfigJson` | `Record<string, unknown>` | 否 | — | **可选**。与 `initialPaintColor` 配套的笔刷配置,上色成功时随 `onPaintCallback` 回传 |
### 识别色与虚线(顶层便捷配置) ### 识别色与虚线(顶层便捷配置)
| 属性 | 类型 | 默认 | 说明 | | 属性 | 类型 | 默认 | 说明 |
| ---- | ---- | ---- | ---- | | -------------------- | --------------------- | -------------------------- | ------------------------------------------ |
| `semanticColors` | `MaskSemanticColor[]` | `MASK_SEMANTIC_COLORS` | 掩码语义识别色,等同 `maskConfig.semanticColors` | | `semanticColors` | `MaskSemanticColor[]` | `MASK_SEMANTIC_COLORS` | 掩码语义识别色,等同 `maskConfig.semanticColors` |
| `regionOutlineColor` | `string` | `rgba(20, 120, 235, 0.58)` | 分区虚线高亮色,等同 `paintConfig.regionOverlayFill` | | `regionOutlineColor` | `string` | `rgba(20, 120, 235, 0.58)` | 分区虚线高亮色,等同 `paintConfig.regionOverlayFill` |
顶层属性优先级高于嵌套 `maskConfig` / `paintConfig` 顶层属性优先级高于嵌套 `maskConfig` / `paintConfig`
`MaskSemanticColor` 结构: `MaskSemanticColor` 结构:
@ -480,8 +487,9 @@ const hasError = watchState === 'error';
### maskConfig ### maskConfig
| 字段 | 类型 | 默认 | 说明 | | 字段 | 类型 | 默认 | 说明 |
| ---- | ---- | ---- | ---- | | ------------------------------ | --------------------- | ------------------------ | ------------------------------------- |
| `semanticColors` | `MaskSemanticColor[]` | 内置色表 | 掩码语义色(可被顶层 `semanticColors` 覆盖) | | `semanticColors` | `MaskSemanticColor[]` | 内置色表 | 掩码语义色(可被顶层 `semanticColors` 覆盖) |
| `blackThreshold` | `number` | `30` | BGR 最大值低于此值的像素视为黑色背景 | | `blackThreshold` | `number` | `30` | BGR 最大值低于此值的像素视为黑色背景 |
| `maxRegionColors` | `number` | `6` | 最终保留的最大语义分区数 | | `maxRegionColors` | `number` | `6` | 最终保留的最大语义分区数 |
@ -505,12 +513,14 @@ const hasError = watchState === 'error';
| `splitWallsChromaBlurRadius` | `number` | `5` | 预留:色度平滑半径 | | `splitWallsChromaBlurRadius` | `number` | `5` | 预留:色度平滑半径 |
| `splitWallsNeutralChromaMax` | `number` | `14` | 白/灰墙低饱和判定半径;与有色墙强制分界 | | `splitWallsNeutralChromaMax` | `number` | `14` | 白/灰墙低饱和判定半径;与有色墙强制分界 |
开启 `splitWalls` 后,原有单一 `wall` 区域会被替换为多个 `wall-N` 子区,各自独立上色与撤销。旧 Session 中 `regionName: 'wall'` 无法映射到新子区名,需重新上色。 开启 `splitWalls` 后,原有单一 `wall` 区域会被替换为多个 `wall-N` 子区,各自独立上色与撤销。旧 Session 中 `regionName: 'wall'` 无法映射到新子区名,需重新上色。
### pipelineConfig ### pipelineConfig
| 字段 | 类型 | 默认 | 说明 | | 字段 | 类型 | 默认 | 说明 |
| ---- | ---- | ---- | ---- | | -------------------------- | -------- | ------- | ----------------------- |
| `maxImageLongSide` | `number` | `720` | 分割 / pickMap / 工作区缩放最长边 | | `maxImageLongSide` | `number` | `720` | 分割 / pickMap / 工作区缩放最长边 |
| `paintFreqMaxLongSide` | `number` | `480` | OpenCV LAB 高低频最长边 | | `paintFreqMaxLongSide` | `number` | `480` | OpenCV LAB 高低频最长边 |
| `originPreviewMaxLongSide` | `number` | `360` | 预览最长边(主路径走工作区分辨率) | | `originPreviewMaxLongSide` | `number` | `360` | 预览最长边(主路径走工作区分辨率) |
@ -519,10 +529,12 @@ const hasError = watchState === 'error';
| `contourApproxEpsilon` | `number` | `0.003` | 轮廓多边形逼近系数 | | `contourApproxEpsilon` | `number` | `0.003` | 轮廓多边形逼近系数 |
| `maxRegions` | `number` | `500` | 分割阶段最大区域数上限 | | `maxRegions` | `number` | `500` | 分割阶段最大区域数上限 |
### paintConfig ### paintConfig
| 字段 | 类型 | 默认 | 说明 | | 字段 | 类型 | 默认 | 说明 |
| ---- | ---- | ---- | ---- | | -------------------------- | ------------ | ----------------------- | -------------------------- |
| `palette` | `BgrColor[]` | 6 色内置盘 | 底部笔刷色条 | | `palette` | `BgrColor[]` | 6 色内置盘 | 底部笔刷色条 |
| `colorBaseOpacity` | `number` | `0.88` | 底色不透明度 | | `colorBaseOpacity` | `number` | `0.88` | 底色不透明度 |
| `lLightOpacity` | `number` | `0.50` | L 通道叠加强度 | | `lLightOpacity` | `number` | `0.50` | L 通道叠加强度 |
@ -536,10 +548,12 @@ const hasError = watchState === 'error';
| `regionOverlayFill` | `string` | `rgba(20,120,235,0.58)` | 虚线/高亮填充色 | | `regionOverlayFill` | `string` | `rgba(20,120,235,0.58)` | 虚线/高亮填充色 |
| `regionOutlineStrokeWidth` | `number` | `4` | 虚线描边宽度 | | `regionOutlineStrokeWidth` | `number` | `4` | 虚线描边宽度 |
### interactionConfig ### interactionConfig
| 字段 | 类型 | 默认 | 说明 | | 字段 | 类型 | 默认 | 说明 |
| ---- | ---- | ---- | ---- | | ----------------------- | --------- | ------- | ------------------- |
| `pickMapSearchRadiusPx` | `number` | `14` | 点击 pickMap 搜索半径(像素) | | `pickMapSearchRadiusPx` | `number` | `14` | 点击 pickMap 搜索半径(像素) |
| `kickMaskPickRadiusPx` | `number` | `36` | 踢脚线掩码拾取半径 | | `kickMaskPickRadiusPx` | `number` | `36` | 踢脚线掩码拾取半径 |
| `thinStripPadding` | `number` | `0.008` | 细条带(踢脚线)点击扩展比例 | | `thinStripPadding` | `number` | `0.008` | 细条带(踢脚线)点击扩展比例 |
@ -547,6 +561,7 @@ const hasError = watchState === 'error';
| `initRegionFlashMs` | `number` | `1000` | 初始化轮播每条虚线停留毫秒 | | `initRegionFlashMs` | `number` | `1000` | 初始化轮播每条虚线停留毫秒 |
| `enableInitRegionFlash` | `boolean` | `true` | 是否启用初始化轮播 | | `enableInitRegionFlash` | `boolean` | `true` | 是否启用初始化轮播 |
> 完整默认值常量:`DEFAULT_MASK_CONFIG`、`DEFAULT_PIPELINE_CONFIG`、`DEFAULT_PAINT_CONFIG`、`DEFAULT_INTERACTION_CONFIG`(自包入口导出)。 > 完整默认值常量:`DEFAULT_MASK_CONFIG`、`DEFAULT_PIPELINE_CONFIG`、`DEFAULT_PAINT_CONFIG`、`DEFAULT_INTERACTION_CONFIG`(自包入口导出)。
### UI 开关与样式 ### UI 开关与样式
@ -573,12 +588,14 @@ const hasError = watchState === 'error';
### 回调 ### 回调
| 属性 | 签名 | 说明 | | 属性 | 签名 | 说明 |
| ---- | ---- | ---- | | ----------------- | ----------------------------------------- | ---------------------------------- |
| `onWatch` | `(state, durationMs, detail?) => void` | 初始化阶段回调;`durationMs` 自本次 `init` 起算 | | `onWatch` | `(state, durationMs, detail?) => void` | 初始化阶段回调;`durationMs` 自本次 `init` 起算 |
| `onPaintCallback` | `(payload: PaintCallbackPayload) => void` | 上色成功或未选笔刷时点击分区 | | `onPaintCallback` | `(payload: PaintCallbackPayload) => void` | 上色成功或未选笔刷时点击分区 |
| `onError` | `(message, error?) => void` | 分割或加载失败 | | `onError` | `(message, error?) => void` | 分割或加载失败 |
`PaintCallbackPayload`(判别联合,`payload.kind` 区分): `PaintCallbackPayload`(判别联合,`payload.kind` 区分):
```ts ```ts
@ -614,13 +631,15 @@ onPaintCallback={payload => {
`onWatch``detail``MaskSegmentWatchDetail` `onWatch``detail``MaskSegmentWatchDetail`
| 字段 | 类型 | 说明 | | 字段 | 类型 | 说明 |
| ---- | ---- | ---- | | ----------------- | --------- | ----------------- |
| `regionCount` | `number` | 当前有效分区数 | | `regionCount` | `number` | 当前有效分区数 |
| `maskPathsReady` | `boolean` | 轮廓 Skia 路径是否就绪 | | `maskPathsReady` | `boolean` | 轮廓 Skia 路径是否就绪 |
| `freqLayersReady` | `boolean` | 高低频 Shader 纹理是否就绪 | | `freqLayersReady` | `boolean` | 高低频 Shader 纹理是否就绪 |
| `errorMessage` | `string` | `error` 状态下的失败说明 | | `errorMessage` | `string` | `error` 状态下的失败说明 |
#### onWatch 状态流转 #### onWatch 状态流转
``` ```
@ -643,8 +662,9 @@ init
通过 `ref` 调用(类型 `MaskSegmentCanvasRef` 通过 `ref` 调用(类型 `MaskSegmentCanvasRef`
| 方法 | 签名 | 说明 | | 方法 | 签名 | 说明 |
| ---- | ---- | ---- | | ------------------- | ---------------------------------------- | ------------------------------------- |
| `reset` | `() => void` | 撤销上一步上色(按 `paintHistory` | | `reset` | `() => void` | 撤销上一步上色(按 `paintHistory` |
| `swap` | `(showOrigin?: boolean) => void` | 对比原图;不传参 toggle`true`/`false` 显式开关 | | `swap` | `(showOrigin?: boolean) => void` | 对比原图;不传参 toggle`true`/`false` 显式开关 |
| `save` | `(options?) => Promise<SavePaintResult>` | 合成并保存 PNG`options.destDir` 可选输出目录 | | `save` | `(options?) => Promise<SavePaintResult>` | 合成并保存 PNG`options.destDir` 可选输出目录 |
@ -657,6 +677,7 @@ init
| `getRegions` | `() => SegmentRegion[]` | 当前分区列表快照 | | `getRegions` | `() => SegmentRegion[]` | 当前分区列表快照 |
| `getPaintedRegions` | `() => PaintedRegionRecord[]` | 当前上色记录快照 | | `getPaintedRegions` | `() => PaintedRegionRecord[]` | 当前上色记录快照 |
`SavePaintResult``{ filePath, width, height, paintedCount, previewPath? }` `SavePaintResult``{ filePath, width, height, paintedCount, previewPath? }`
代码示例: 代码示例:
@ -832,68 +853,80 @@ MaskSegmentApp/ # 仓库根目录npm 包 react-n
Demo 在挂载画布前调用 `prewarmPngBgrCacheAsync([origin, mask])`PNG 解码命中内存缓存。典型日志: Demo 在挂载画布前调用 `prewarmPngBgrCacheAsync([origin, mask])`PNG 解码命中内存缓存。典型日志:
| 阶段 | watchState | 约耗时 | 说明 | | 阶段 | watchState | 约耗时 | 说明 |
| ---- | ---------- | ------ | ---- | | ------- | -------------------------------- | -------------- | ------------------------------------ |
| 掩码对齐 | `mask_aligned` | ~160ms | 掩码缩放到分割工作分辨率 | | 掩码对齐 | `mask_aligned` | ~160ms | 掩码缩放到分割工作分辨率 |
| 分区完成 | `regions_ready` / `mask_sampled` | ~320ms | 布局扫描 + 踢脚线 + pickMap | | 分区完成 | `regions_ready` / `mask_sampled` | ~320ms | 布局扫描 + 踢脚线 + pickMap |
| **可交互** | **`interactive`** | **~320450ms** | 可点击选区、选色、Shader 上色 | | **可交互** | `**interactive`** | **~320450ms** | 可点击选区、选色、Shader 上色 |
| 轮廓就绪 | `mask_paths_ready` | ~430550ms | 比 `interactive`**~100ms**,轮播虚线可显示 | | 轮廓就绪 | `mask_paths_ready` | ~430550ms | 比 `interactive`**~100ms**,轮播虚线可显示 |
`interactive` **不等待**轮廓路径;`mask_paths_ready` 仅影响初始化轮播虚线与可选 UI 提示。 `interactive` **不等待**轮廓路径;`mask_paths_ready` 仅影响初始化轮播虚线与可选 UI 提示。
同图各子步骤(`__DEV__` 日志,默认 pipeline量级 同图各子步骤(`__DEV__` 日志,默认 pipeline量级
| 子步骤 | 约耗时 | 工作分辨率 | | 子步骤 | 约耗时 | 工作分辨率 |
| ------ | ------ | ---------- | | ----------------- | --------- | ------------------------------ |
| OpenCV LAB 高低频 | ~1040ms | 270×480 | | OpenCV LAB 高低频 | ~1040ms | 270×480 |
| 高低频 Skia 纹理 | ~2030ms | 同上 | | 高低频 Skia 纹理 | ~2030ms | 同上 |
| 布局扫描 + 踢脚线 + 点击查表 | ~90120ms | 405×7201080p 缩至 longSide 720 | | 布局扫描 + 踢脚线 + 点击查表 | ~90120ms | 405×7201080p 缩至 longSide 720 |
| 全量轮廓路径(异步,不阻塞交互) | ~80150ms | 270×480 | | 全量轮廓路径(异步,不阻塞交互) | ~80150ms | 270×480 |
### 分辨率与 `pipelineConfig` 的关系 ### 分辨率与 `pipelineConfig` 的关系
计算密集型步骤被 **最长边上限** 截断,**不随 4K/8K 原图线性放大****PNG 全图解码**仍随像素量线性增长。 计算密集型步骤被 **最长边上限** 截断,**不随 4K/8K 原图线性放大****PNG 全图解码**仍随像素量线性增长。
| 步骤 | 配置项 | 1080×1920 实际处理尺寸 | 随原图像素增长 | | 步骤 | 配置项 | 1080×1920 实际处理尺寸 | 随原图像素增长 |
| ---- | ------ | ---------------------- | -------------- | | -------------- | --------------------------- | ---------------- | ------------------------ |
| PNG 解码 | — | 1080×1920 × 2 张 | **是** | | PNG 解码 | — | 1080×1920 × 2 张 | **是** |
| 掩码分割 / pickMap | `maxImageLongSide: 720` | ~405×720 | **否**(长边 >720 时固定) | | 掩码分割 / pickMap | `maxImageLongSide: 720` | ~405×720 | **否**(长边 >720 时固定) |
| Shader 高低频 | `paintFreqMaxLongSide: 480` | ~270×480 | **否** | | Shader 高低频 | `paintFreqMaxLongSide: 480` | ~270×480 | **否** |
| 工作区 Skia 原图 | 同 `maxImageLongSide` | ~405×720 | **否** | | 工作区 Skia 原图 | 同 `maxImageLongSide` | ~405×720 | **否** |
| 虚线轮廓 | `maskPathMaxLongSide: 480` | ~270×480 | **否**(不阻塞 `interactive` | | 虚线轮廓 | `maskPathMaxLongSide: 480` | ~270×480 | **否**(不阻塞 `interactive` |
### `interactive` 预估(默认 pipeline ### `interactive` 预估(默认 pipeline
| 原图规格 | 相对 1080p 像素 | 有 PNG 预热 | 冷启动(无预热) | | 原图规格 | 相对 1080p 像素 | 有 PNG 预热 | 冷启动(无预热) |
| -------- | --------------- | ----------- | ---------------- | | -------------- | ----------- | ------------- | -------------- |
| 1080×1920 | 1× | **320450ms** | **450700ms** | | 1080×1920 | 1× | **320450ms** | **450700ms** |
| 1440×2560 (2K) | ~1.8× | **400550ms** | **600900ms** | | 1440×2560 (2K) | ~1.8× | **400550ms** | **600900ms** |
| 3840×2160 (4K) | ~4× | **500750ms** | **8001200ms** | | 3840×2160 (4K) | ~4× | **500750ms** | **8001200ms** |
| 7680×4320 (8K) | ~16× | **0.81.5s** | **1.53s+** | | 7680×4320 (8K) | ~16× | **0.81.5s** | **1.53s+** |
> **300ms 内可交互**:在 1080p + 预热 + 默认 pipeline + 中高端机上**接近但偏乐观**;不宜作为全机型 SLA。 > **300ms 内可交互**:在 1080p + 预热 + 默认 pipeline + 中高端机上**接近但偏乐观**;不宜作为全机型 SLA。
### 机型档位1080p默认 pipeline ### 机型档位1080p默认 pipeline
相对上述开发环境 ~320ms 的量级: 相对上述开发环境 ~320ms 的量级:
| 档位 | 相对倍数 | 有预热 `interactive` | 冷启动 | | 档位 | 相对倍数 | 有预热 `interactive` | 冷启动 |
| ---- | -------- | -------------------- | ------ | | -------------------- | -------- | ----------------- | ---------- |
| 旗舰 iOS / 新旗舰 Android | 0.81.2× | 300450ms | 500800ms | | 旗舰 iOS / 新旗舰 Android | 0.81.2× | 300450ms | 500800ms |
| 中端 Android | 1.52.5× | 500800ms | 700ms1.2s | | 中端 Android | 1.52.5× | 500800ms | 700ms1.2s |
| 低端 Android4GB、老 U | 2.54× | 800ms1.3s | 12s+ | | 低端 Android4GB、老 U | 2.54× | 800ms1.3s | 12s+ |
Android 额外开销主要来自JS ↔ OpenCV bridge、内存带宽/GC、Skia 纹理上传。 Android 额外开销主要来自JS ↔ OpenCV bridge、内存带宽/GC、Skia 纹理上传。
### 提高 `maxImageLongSide` 的影响 ### 提高 `maxImageLongSide` 的影响
若将 `pipelineConfig.maxImageLongSide` 设为 **1280**(高于默认 720分割工作区约 **720×1280**,像素约为 720 档的 **3×** 若将 `pipelineConfig.maxImageLongSide` 设为 **1280**(高于默认 720分割工作区约 **720×1280**,像素约为 720 档的 **3×**
| 场景 | 默认 720 | 改为 1280 | | 场景 | 默认 720 | 改为 1280 |
| ---- | -------- | --------- | | ------------------------ | ---------- | ------------- |
| 1080p `interactive`(中端机) | ~320800ms | **500ms1s+** | | 1080p `interactive`(中端机) | ~320800ms | **500ms1s+** |
| 分割 / pickMap 耗时 | ~90120ms | ~250350ms | | 分割 / pickMap 耗时 | ~90120ms | ~250350ms |
更高精度换更长初始化;若目标仍是 **<500ms 可交互**建议维持默认 **720**必要时降至 **640** 更高精度换更长初始化;若目标仍是 **<500ms 可交互**建议维持默认 **720**必要时降至 **640**
### 优化建议 ### 优化建议
@ -907,10 +940,10 @@ await prewarmPngBgrCacheAsync([originPath, maskPath]);
// 再挂载 MaskSegmentCanvas // 再挂载 MaskSegmentCanvas
``` ```
2. **Loading 时机**:阻塞式 Loading 在 `interactive` 关闭;「轮廓准备中」可选监听 `mask_paths_ready` 1. **Loading 时机**:阻塞式 Loading 在 `interactive` 关闭;「轮廓准备中」可选监听 `mask_paths_ready`
3. **大图 / 低端机**:保持默认 `maxImageLongSide: 720`;可再将 `paintFreqMaxLongSide` 降至 **360** 2. **大图 / 低端机**:保持默认 `maxImageLongSide: 720`;可再将 `paintFreqMaxLongSide` 降至 **360**
4. **4K 素材**:业务侧先下采样再传入,或接受 **0.81.5s** 量级的 `interactive`(预热后)。 3. **4K 素材**:业务侧先下采样再传入,或接受 **0.81.5s** 量级的 `interactive`(预热后)。
5. **观测**:开发环境关注 Metro 中 `[MaskSegment]`、`[⏱ ...]` 与 `onWatch``durationMs` 4. **观测**:开发环境关注 Metro 中 `[MaskSegment]`、`[⏱ ...]` 与 `onWatch``durationMs`
--- ---