27 寸 4K 开 125% 为什么发虚?PPI 和缩放一次算清

27 寸 4K 在 60cm 看,PPI 是 163.18,肉眼分辨阈值只有 145.53,单个像素根本看不见。

同一块屏开到 125%,1 个 CSS 像素要摊到 1.25 个设备像素上,老程序的位图就被拉出两列灰边。

我把这套换算做成一个离线网页,输入对角线、分辨率、观看距离,PPI、点距、阈值、结论和缩放灰边一次算清。页内 12 条断言,12/12 通过。

在线案例与源码:gitcode.com/OPCTeam/dem... 成品只有一个 index.html,双击就能打开。

一、为什么值得看:4K 的清晰和 125% 的发虚是两件事

PPI 的算法很直白:对角线上的像素总数除以对角线英寸数。

像素总数是宽高的平方和再开方,27 寸 3840×2160 算出来是 4405.8,除以 27 得 163.18 PPI。

点距是它的倒数,25.4 除以 163.18,得到 0.1557 毫米。

我把 24 寸 1080p 也放进去比了一下,91.79 PPI,点距 0.2767 毫米,像素块大了一半多。

真正决定「看不看得出像素」的不是 PPI,是 PPI 和观看距离的比值。

人眼的分辨极限常用 1 弧分来算,换算成屏幕就是 87319 除以距离毫米数。

60cm 时阈值是 145.53 PPI。27 寸 4K 的 163.18 除以 145.53 等于 112%,过了线。

同样 60cm,27 寸 2K 只有 108.79 PPI,比值 75%,结论就变成能看出像素颗粒。

把距离拉到 80cm,阈值降到 109.15 PPI。27 寸 2K 的 108.79 刚好卡在 99.7%,属于临界。

这张表是页面里七种屏幕的实测值,阈值统一按 60cm 算。

屏幕 PPI 点距 60cm 阈值 结论
24 寸 1080p 91.79 0.2767 mm 145.53 能看出颗粒
24 寸 2K 122.38 0.2075 mm 145.53 接近临界
27 寸 2K 108.79 0.2335 mm 145.53 能看出颗粒
27 寸 4K 163.18 0.1557 mm 145.53 看不出像素
32 寸 4K 137.68 0.1845 mm 145.53 接近临界
16 寸 2K+ 188.68 0.1346 mm 145.53 看不出像素
6.1 寸手机 457.25 0.0555 mm 145.53 看不出像素

32 寸 4K 是个容易被忽略的反例:分辨率比 27 寸 2K 高,PPI 却只比它多 28.9,60cm 只是接近临界,还谈不上看不出。

尺寸一大,同样的 3840×2160 被摊薄了。

二、准备环境:进入码道 Web

浏览器打开码道 Web 版:devcloud.cn-north-4.huaweicloud.com/chat?source...

码道有三种使用方式:WebUI(浏览器对话)、TUI(终端命令行)和桌面 IDE(IDE 插件)。本文用 WebUI 版演示。

三、需求原文:把公式和断言写死

这一轮我把所有公式、期望值和 12 条断言都写进了需求,不让模型自己回忆。

断言里最关键的是第 10 条:200% 整数缩放的灰边宽度必须是 0,125% 必须大于等于 1。

第一版交付时页面显示 11/12,第 10 条 FAIL,实测值写着「200%: 2, 125%: 2」。

这不是显示错误,是代码真把 200% 算出了灰边。

四、实测:三张图、两张表、12 条断言

像素对比区固定了 120 毫米的物理宽度,按 91.8 / 108.8 / 163.2 PPI 换算出 434 / 514 / 771 像素。

三张画布先按各自的真实像素宽度画同一段「清晰度测试 Abc123」,再关掉平滑放大到 320 宽。

91.8 PPI 那张的字边缘是整块整块的方格,163.2 PPI 那张已经接近平滑。

缩放区没有用画布插值,改成一条 40 列的一维数组,第 20 列是黑,其余是白。

按 1.0 / 1.25 / 1.5 / 2.0 重采样到 40 / 50 / 60 / 80 列,再逐列数非纯黑非纯白的像素。

缩放 1 CSS px 对应 灰边宽度 判断
100% 1.00 设备 px 0 列 整数倍,干净
125% 1.25 设备 px 2 列 非整数,发虚
150% 1.50 设备 px 2 列 非整数,发虚
200% 2.00 设备 px 0 列 整数倍,干净

12 条断言跑完是 12/12。A1 到 A3 分别量出 163.18、108.79、91.79 PPI。

A4 量点距 0.1557 mm,A5 量 60cm 阈值 145.53 PPI,A11 量手机 457.25 PPI。

A6 和 A7 判结论,A8 和 A9 判 1 CSS 像素对应几个设备像素,A12 判错误提示。

我把 24 寸 1080p 那组参数改到 40cm 又跑了一遍,PPI 还是 91.79,阈值升到 218.30,比值掉到 42%。

结论直接从「接近临界」翻成「能看出像素颗粒」。

这也解释了为什么同一台显示器,坐远一点觉得细腻,凑近看全是格子。

五、踩坑:200% 也被算出了灰边

第一版的 resampleColumns 只有一套双线性公式,100% 到 200% 全走它。

200% 时采样点落在两个源像素正中间,插值出 0.5 的灰,页面就报「200%: 2」。

真实显示器的整数缩放是复制像素,不是插值。2 倍就是每个像素画成 2×2,边缘不该有灰。

我把整数倍单独分出来,直接取源列复制;非整数倍才走双线性。

改完再跑,200% 的灰边变成 0,125% 仍然是 2,A10 通过,12/12。

第二个坑在像素对比图。第一版字号按画布高度算,434 像素那张写不下整句,左右各被裁掉一截,截图里只剩「度测试 Abc」。

后来加了一个循环,用 measureText 量宽度,超宽就把字号减一,直到塞得进画布减 6 像素。

错误路径也实测了。我把对角线填成 0,参数区下方立刻出现红条「对角线必须大于 0」。

上面的 163.18 PPI、0.1557 mm、145.53 PPI 全部保留,没有变成 NaN,也没有清空。

六、边界:这是换算和模拟,不是显示器实测

页面上的 PPI 和点距是算出来的,前提是像素为正方形,而且屏幕没有做非原生分辨率缩放。

阈值用的是 1 弧分的标准视力,个体差异很大,戴眼镜和不戴眼镜的结果就不一样。

缩放区的灰边是一条一维竖线的重采样结果,只回答「整数倍和分数倍在采样上的区别」。

浏览器里的矢量文字仍然按设备像素重绘,真正发虚的主要是位图素材和老式 GDI 程序。

125% 下现代应用里的文字大多还是清楚的,别把这张图当成「所有界面都会糊」。

七、使用码道体会

  • 公式和期望值直接写进需求,模型就没有「大概」「差不多」的空间。
  • 断言必须显示实测值,不能只写一个 true。这次 A10 就是靠「200%: 2」这行数字抓到的。
  • 自检放在页面里,交付时能当场点开,文章里的 12/12 才有出处。
  • 整数倍和分数倍这种边界,提前写成一条断言,比事后手测快得多。
  • 截图前把每一张放大看一遍。第一版文字被裁掉一截,就是放大后才发现。
  • 错误路径也要给断言:填 0 必须报中文错,而且不能清空上一次的结果。

八、结果与下一步

选显示器时,先量一下平时的观看距离,再拿 PPI 和「87319 除以距离毫米数」的得数比一比。

60cm 桌面前,27 寸 4K 的 112% 很稳,27 寸 2K 的 75% 能看出颗粒,24 寸 1080p 只有 63%。

80cm 沙发距离,27 寸 2K 的 99.7% 刚好够用,再低就该上 4K 了。

缩放优先选 100% 或 200% 这类整数倍。125% 和 150% 不是不能用,是要接受位图素材多出两列灰边。

成品和源码都在这里:gitcode.com/OPCTeam/dem...

下一步想补两块:带鱼屏的等效 PPI,以及 macOS 的 HiDPI 缩放和 Windows 的整数缩放有什么不同。

相关推荐
广州华水科技17 分钟前
当大坝面临风险时,如何有效实施单北斗GNSS变形监测?
前端
AiMan1 小时前
Poe还是不可以导出左侧所有对话,只能单条内容导出,方法不对吗
前端
AiMan2 小时前
文心生成的内容能否下载吗?
前端
前端双越老师2 小时前
程序员 1v1 访谈系列第十四期:接受焦虑 拥抱不确定
前端·ai编程·全栈
deli0073 小时前
MCP 协议 6 条消息拆开看:AI 为什么能自己读文件调接口
前端
风骏时光牛马3 小时前
请告诉我标题对应的内容、想要的风格,我马上给你生成。
前端
deli0074 小时前
OAuth 2.0 授权码流程实测:4 次跳转,少个 state 就被劫持
前端
deli0076 小时前
手机20%突然关机?电量百分比是估的,SOC曲线4组实测
前端