清理抠图旧管线与过期测试

更新手动去背景 Data URL 测试为 OSS object key 调用顺序

删除 platform-matting 无调用的图片字节抠图入口

修正角色形象 BgFilter image_url 文档契约
This commit is contained in:
2026-07-17 13:01:13 +00:00
parent 68283c9469
commit 83dbbe404c
4 changed files with 4 additions and 55 deletions
@@ -65,7 +65,7 @@
角色设定:<用户输入的角色设定>
```
- 角色图生成完成后,编辑器后端必须先把带自动决策纯色背景的源图写入 OSS,再调用共享 BgFilter 服务透明化multipart 字段包含 `file``screen_color=<screenColor>``seg_model=<segModel>``background_mode=flat``cross_check=on`,用户路径默认并只提交 `seg_model=birefnet``flat` 明确表示单一纯色背景抠图模式,`birefnet` 是 BgFilter 管线内部后端。首次请求失败后立即重试 `1` 次,第二次仍失败进入“阿里云通用抠图 → 本地键色”降级链。角色图 prompt 按 `screenColor` 写入颜色名称、hex 和 RGB。该流程不再调用 RPG / 资产工坊的角色主图专用 `character_visual_assets` 后处理,也不复用手动去背景的 `background_mode=complex` 路径。透明背景处理正常成功时,输出透明背景 PNG,随后写入 OSS 私有对象并确认 `asset_object`;接口回包返回透明 PNG Data URL 及 `objectKey` / `assetObjectId`。三段透明背景处理最终仍失败、但 provider 原图已经持久化时,任务以 `completed + warning` 收口,只把 provider 原图作为唯一主图放入画布,`generatedLayerId` 指向原图,不创建不存在的透明处理图;通用 `warning.code/reason` 携带完整降级原因。该收口只捕获透明背景处理本身的最终失败;phase 上报、provider 原图持久化、透明处理图持久化和 `canvasCompletion` 写回错误仍正常传播,不能被原图降级吞掉。前端创建图层和画板资源记录时必须保存最终回包对应的媒体引用。
- 角色图生成完成后,编辑器后端必须先把带自动决策纯色背景的源图写入私有 OSS,再签发 600 秒 GET URL 调用共享 BgFilter 服务透明化api-server 不重新下载原图,multipart 字段包含 `image_url``screen_color=<screenColor>``seg_model=<segModel>``background_mode=flat``cross_check=on`不包含 `file`用户路径默认并只提交 `seg_model=birefnet``flat` 明确表示单一纯色背景抠图模式,`birefnet` 是 BgFilter 管线内部后端。首次请求失败后立即重试 `1` 次,第二次仍失败进入“阿里云通用抠图 → 本地键色”降级链。角色图 prompt 按 `screenColor` 写入颜色名称、hex 和 RGB。该流程不再调用 RPG / 资产工坊的角色主图专用 `character_visual_assets` 后处理,也不复用手动去背景的 `background_mode=complex` 路径。透明背景处理正常成功时,输出透明背景 PNG,随后写入 OSS 私有对象并确认 `asset_object`;接口回包返回透明 PNG Data URL 及 `objectKey` / `assetObjectId`。三段透明背景处理最终仍失败、但 provider 原图已经持久化时,任务以 `completed + warning` 收口,只把 provider 原图作为唯一主图放入画布,`generatedLayerId` 指向原图,不创建不存在的透明处理图;通用 `warning.code/reason` 携带完整降级原因。该收口只捕获透明背景处理本身的最终失败;phase 上报、provider 原图持久化、透明处理图持久化和 `canvasCompletion` 写回错误仍正常传播,不能被原图降级吞掉。前端创建图层和画板资源记录时必须保存最终回包对应的媒体引用。
-`assetKind: "character"` 的角色图层执行 `重绘` 时,前端仍使用原图作为参考图,但请求 `kind` 必须传 `character`,让后端继续套用上述角色提示词限定、角色图后处理和角色资产持久化;透明背景正常成功与最终失败保留 provider 原图的收口规则和角色新生成一致。普通图片图层重绘仍保持 `kind: "quick-edit"`
## 生成规范参考图
@@ -112,7 +112,6 @@ mod tests {
let body = &tail[..end];
assert!(body.contains("segment_image_url_to_transparent_png"));
assert!(!body.contains("segment_image_to_transparent_png(image.bytes"));
}
#[test]
@@ -9669,7 +9669,9 @@ mod tests {
&[
"ensure_editor_background_removal_source_is_not_data_url",
"caller.report_processing_phase(state).await?",
"parse_editor_reference_image",
"resolve_editor_reference_object_key",
"ensure_editor_reference_object_key_owned",
"request_editor_background_removal_image_with_retry",
],
);
}
@@ -381,58 +381,6 @@ impl MattingClient {
})
}
/// 图片字节 → 通用抠图 → 原尺寸透明 PNG 字节。
///
/// - 输入统一经 AuthorizeFileUpload 单对象 Policy 上传临时 OSS 后作为 ImageURL 送抠。
/// - 分辨率守卫:任一边 >= 2000 时先等比缩小送抠,抠完只取结果 alpha 上采样回贴
/// 原图 RGB,保证输出与输入同尺寸、画质无损。
pub async fn segment_image_to_transparent_png(
&self,
bytes: &[u8],
file_name: &str,
) -> Result<Vec<u8>, MattingError> {
let source = decode_source_image(bytes)?;
let source_rgba = source.to_rgba8();
let (source_width, source_height) = source_rgba.dimensions();
// 阿里云要求每条边 > 32px;过小的图直接拒绝,让调用方走本地兜底,省一次注定 4xx 的往返。
if source_width <= MIN_INPUT_EDGE || source_height <= MIN_INPUT_EDGE {
return Err(MattingError::InvalidRequest(format!(
"待抠图图片尺寸 {source_width}x{source_height} 过小,阿里云通用抠图要求每条边大于 {MIN_INPUT_EDGE} 像素"
)));
}
// 归一化成阿里云 SegmentCommonImage 接受的输入:统一 8 位 RGBA PNG(消除 MIME 名不副实
// 与不支持位深/格式的问题)、最长边 ≤1999、体积 ≤3MB。返回实际上传尺寸,用于判断结果
// 是否需要 alpha 上采样回原尺寸。
let (upload_bytes, upload_dims) = normalize_matting_input_png(&source)?;
let downscaled = upload_dims != (source_width, source_height);
let image_url = self
.upload_temp_image(upload_bytes, file_name, "image/png")
.await?;
let result_image = self
.segment_uploaded_input_to_rgba(image_url, (source_width, source_height), upload_dims)
.await?;
if !downscaled {
if result_image.dimensions() != (source_width, source_height) {
return Err(MattingError::upstream_response_error(
format!(
"抠图结果尺寸 {}x{} 与输入 {}x{} 不一致",
result_image.width(),
result_image.height(),
source_width,
source_height
),
None,
));
}
return encode_rgba_png(&result_image);
}
compose_source_with_result_alpha(source_rgba, result_image)
}
/// 私有 OSS 签名 URL → 下载 → AuthorizeFileUpload 临时对象 → 通用抠图 → 透明 PNG。
///
/// 源图下载缓冲和解码图只活到临时对象上传完成;若输入发生过降尺寸,结果返回后再单独下载