手机屏幕替换
照片:$ARGUMENTS。如果没有,则要求提供一张,或使用 find_photos.py 查找。
整个手机正面通过代码被替换:屏幕、黑色边框以及刘海或灵动岛。玻璃以外的照片部分保持不变。
对于已经存在的模板,此技能无需使用:python3 swap.py <image>。
新模板
获取:一张真实的iPhone照片,屏幕正对相机。跳过:Android、倾斜超过25°、一边长度超过另一边1.2倍(裁剪会拒绝它们)。跳过手指或袖子遮挡屏幕的照片: 如果没有灰色边框,会覆盖在屏幕上。整个玻璃区域(包括上面的眩光)都属于我们。只有从外部进入的皮肤部分保留在照片中。
P=<name, 8 characters, unique>; D=templates/corners
mkdir -p out
# 1. 查看照片并读取屏幕的大致角点:TL,TR,BR,BL
python3 tools/slide_crop.py --q '<corners>' <photo.jpg> templates/crop/$P.jpg # 在裁剪图上打印角点
# 2. 精确的直边。如果 `live` 较低:R=34
python3 tools/slide_lines.py $P '<corners on the crop>' out/l.jpg # 输出末尾的精确角点
# 3. 轮廓:透视、镜头弯曲、半径、玻璃轮廓
python3 tools/slide_trace.py $P '<corners>' out/t.jpg $D/$P.json
# 4. 验证拟合未覆盖的部分。务必查看图片
python3 tools/slide_proof.py $P $D/$P.json out/$P-proof.jpg
# 5. 姿态,仅用于反射
python3 tools/slide_sheet.py $P $D/$P.pose.json init
# 6. 测量刘海或灵动岛、状态图标、黑色区域
python3 tools/slide_check.py $P measure
# 配方 $D/$P.recipe.json:复制 a841f108(刘海)或 f5dad639(灵动岛),然后设置 frame=$P、pose、corners 以及测得的选项
# 7. 将时间和图标调整到该手机的位置
python3 tools/slide_status.py $P init <line from measure>; python3 tools/slide_status.py $P build
# 8. 构建并进行红色测试
python3 tools/slide_check.py $P build
# 9. 泄漏热图
python3 tools/slide_check.py $P leak
# 10. 边框宽度
python3 tools/slide_check.py $P frame
完成之后,它就是一个模板:python3 swap.py <image> -t $P。
相信之前先检查
out/$P-split.jpg: 照片、红色、结果。红色拟合到位,边框完整覆盖手机壳边缘,从主体向内的一切都属于我们。out/$P-leak.jpg: 黑色屏幕上的边框,亮度采用对数标度。任何发光部分都来自照片:切割边缘的线条、斑点、眩光。只有扬声器和真正突出物才会显示。out/$P-top.jpg: 照片上切割部分的绿色轮廓,图标到位。out/$P-zoom.jpg: 角落和边框放大图,旁边是照片。- 通过
swap.py使用白色图像的模板:深色页面会暴露不良的角落和边缘。 out/$P-frame.jpg: 白色屏幕上的四个角点。在通过以下边框检查之前,模板不算完成。
边框检查
黑色边框是硬件,四周宽度一致。slide_check.py $P frame 在白色屏幕上构建,将其拉直并测量每侧中部的黑色宽度,单位为截图像素(591 宽)。它会分别打印 ours 和 photo 各侧的值、差异以及判定:最多 4 像素为 OK,超过则为 FIX。
4 像素的限值是根据这些手机确定的:7.5 像素的差异明显可见,而 4 像素则看不出来。
如果新模板显示 FIX:
- 重新运行
slide_trace.py:它会读取可见的黑色区域,并为每侧取中位数(frame:行)。 - 重新构建,然后再次运行
frame。 - 仍然显示
FIX:比较ours和photo。如果它们匹配,说明照片中该侧的边框被眩光、手机壳或手遮挡住了。如果不匹配,则轮廓有误:查看-frame.jpg和-split.jpg。 - 如果无法收敛,则不要将模板标记为完成。说明是哪一侧偏差以及偏差的像素数。
也请目视检查
-frame.jpg:顶部和侧面应该匹配。 已发布的模板:f38fe44a2.2、791866583.2 和895d3ee83.8 通过。f5dad6395.8、a841f1086.2 和14278a0b8.5 未通过:它们的边框保持首次构建时的状态。
设置
- 黑色:
floor,使边框和切割部分与照片匹配。从.003开始,如果照片更暗则降低。build会打印两者。 - 刘海: 来自
measure的值。根据绿色轮廓调整cr,measure读取的值偏低。 - 刘海上的扬声器:
grille=45。如果旧页面的一条细线出现在刘海周围:gband=1。 - 灵动岛: 其中心是硬件,位于 591 中的 295.5。如果
measure显示偏差超过 1 像素,说明某个亮部吞噬了边缘:取干净的边缘并通过中心镜像。在锁定屏幕上,从带有灵动岛的手机(时间 111,图标 479)获取x,从measure获取y。 - 灵动岛上方的扬声器: 如果位于玻璃轮廓内部,
grille=45只恢复其浮雕。 - 玻璃上的袖子:
sleeve=1,仅当templates/grey/(f38fe44a)中存在真实的灰色边框时使用。 - 暗对暗: 当 720 个点中少于 400 个上升时,
slide_trace.py会自动切换。请额外仔细检查-split。
工作原理
手机是刚性的,因此屏幕是一个带有 iOS 连续圆角的矩形,通过透视和一个径向镜头弯曲观察。边缘在对数亮度中查找,因此暗对暗也能工作,并在线性光线的中点处放置。图像绘制在拉直的照片上,然后通过玻璃反向弯曲。
已知陷阱
- 仅通过深色页面判断。
- 用一种方式拟合却用另一种方式检查:检查就是拟合本身,而验证才是检查被排除的内容。
- 直接在照片上画直线:照片是弯曲的。直线只存在于拉直后的图像上。
- 在亮屏上从外向内搜索手机壳边缘:布料的褶皱看起来像手机壳。应从屏幕向外搜索。