清理抠图旧管线与过期测试
更新手动去背景 Data URL 测试为 OSS object key 调用顺序 删除 platform-matting 无调用的图片字节抠图入口 修正角色形象 BgFilter image_url 文档契约
This commit is contained in:
@@ -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。
|
||||
///
|
||||
/// 源图下载缓冲和解码图只活到临时对象上传完成;若输入发生过降尺寸,结果返回后再单独下载
|
||||
|
||||
Reference in New Issue
Block a user