Skip to content

fix(video): 首帧按目标画布等比放大并显式合成底色 - #511

Merged
johnnyzhang-eng merged 2 commits into
1024XEngineer:mainfrom
johnnyzhang-eng:fix/i2v-first-frame-contain
Aug 21, 2026
Merged

fix(video): 首帧按目标画布等比放大并显式合成底色#511
johnnyzhang-eng merged 2 commits into
1024XEngineer:mainfrom
johnnyzhang-eng:fix/i2v-first-frame-contain

Conversation

@johnnyzhang-eng

@johnnyzhang-eng johnnyzhang-eng commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

Closes #509

背景

i2v 首帧预处理与图片链路的交付契约错位:图片链路交付透明 PNG,视频适配器按不透明图处理。

问题

_fit_first_frame 两处缺陷叠加在同一个函数里。

一是 convert("RGB") 直接丢 alpha。透明像素的 RGB 是未定义值,抠图输出里恰好是 0,于是视频输入静默变成黑底;补边色取自角点,同样落到黑。抠图靠主体与底色的距离判前景,黑底会把角色暗部判成背景。

二是 thumbnail() 只缩不放。小于目标画布的输入原尺寸居中贴入,主体有效分辨率按源边长与画布边长之比被砍掉,之后 i2v 与重抠图都补不回来。序列帧路径同款问题已在 2026-08-11 换掉实现(_require_size),母版与首帧这两条没有跟着换。

方案

RGBA / LA / 带 transparency 的 P 图先合成到具名常量 _FIRST_FRAME_BG(中灰),补边用同色;不透明输入仍沿用角点色,行为不变。缩放改为双向等比 contain,先算 scale 再 resize,可放大可缩小,比例不变。底色做成模块常量而不是配置项:配置项会让各环境的值悄悄分叉,而这个值有测量依据。alpha 分支的判据照 media/service.pybuild_card_thumbnail 的同一写法。

不包含

前后对照

同一张已确认首帧,经首帧预处理后真正提交给 i2v 的那张图。两条实现各自从源码跑,未调用生成接口。

首帧预处理前后对照

左列是已确认首帧(棋盘格=透明),中列现行实现,右列本 PR。现行实现下主体占幅 28%、背景是黑底;修复后内容区 720×720、主体占幅 75~79%、底色是声明的中灰。

第三行 #148 是配对里唯一 IoU 下降的样本:它的源图自带一块不透明浅色底板,原有 alpha 把整块底板算成了主体,修复后抠图找到真物体,所以 IoU 反而降到 0.332 —— 是参考值坏,不是修复退步。

验收

用 18 张真实的、确实抠过图的母版首帧做配对比较(同一张图过两条实现,未调用任何生成接口)。

主体占幅(重抠图后主体高度 / 画布高度)中位 0.27 → 0.72,18/18 张全部变好,配对均差 +0.413 ± 0.025。

重抠图往返 IoU(恢复出的 alpha 与原 alpha)中位 0.843 → 0.954,17/18 张变好。配对均差 +0.067 ± 0.045,按两倍标准误判分不开,因为被一个坏参考样本拉平:那张素材源图自带一块不透明浅色底,它原有的 alpha 本身就把整块底当成了主体,修复后抠图找到了真物体,IoU 反而下降。此处判据取符号检验而不是均差。

底色选中灰的依据:黑底 IoU 中位 0.900,中灰 0.954,16/18 张中灰更好;白底与中灰分不开(0.963 vs 0.954),但中灰的尾部更小,IoU 低于 0.8 的比例 11.1% 对 22.2%。放大滤波 LANCZOS 与 NEAREST 配对均差 +0.0043 ± 0.0014,取 LANCZOS。

新增用例四组,含五种源尺寸乘有无 alpha 的参数化:等比放大且主体占幅保持、方形输入在 1280x720 里形成 720x720 内容区且左右各补 280、合成底色是声明值且不随未定义 RGB 变化、不透明输入仍取角点色补边。把 sufy.py 换回修复前版本跑这批用例:11 个失败,唯一通过的是不透明输入那条回归护栏,两边都该过。

ruff check .lint-imports(2 kept, 0 broken)、pytest 全量 1212 passed / 14 skipped。

RGBA 首帧不再 convert("RGB") 读未定义的透明像素 RGB,改为合成到具名底色;
thumbnail 只缩不放换成双向等比 contain,小 sprite 先放大再补边。

Closes 1024XEngineer#509
@vercel

vercel Bot commented Aug 21, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
windup Ignored Ignored Preview Aug 21, 2026 6:05am

@github-actions

github-actions Bot commented Aug 21, 2026

Copy link
Copy Markdown

✅ 此 PR 已关联 issue,之前的提醒已自动标记为已解决。

@fennoai fennoai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

已检查固定提交范围 d587dc85e03dd60ce34ca4370e520bf6eb7754e6...e51c1116e104a920c434658adc8d4dc5279981a1,覆盖首帧缩放/透明背景处理及新增回归用例。未发现满足报告标准的可操作 correctness、性能或安全问题。

验证:python -m py_compile 通过,git diff --check 通过;未运行 pytest,因为当前环境未安装 pytest 及项目运行依赖。

@codecov

codecov Bot commented Aug 21, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@xyh202131 xyh202131 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

已复核当前提交:i2v 首帧按目标画布等比放大或缩小,透明输入先合成稳定底色,不透明输入保持角点补边逻辑;尺寸、透明模式和回归护栏测试完整。当前 CI 全部通过且无未解决审查线程。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: i2v 首帧预处理丢失 alpha 且不放大小尺寸 sprite,导致截帧从首帧起退化

2 participants