perf(share): 用「同画布放大二维码」替代 2x 渲染,模块 4px → 5px
960×540 的卡被聊天软件缩到 480 宽时,二维码每模块只剩 2px,解码器读不出。 2x 渲染能解决,但实测成本不低(见下),先用零代价的办法把模块做大。 实测矩阵(go-qrcode 纠错 Q / 真实 55 字符链接 / 37 模块,含内嵌头像): 尺寸 148px = 4.0px/模块 -> 960 o 720 o 480 x 320 x 尺寸 190px = 5.0px/模块 -> 960 o 720 o 480 o 320 o 240 x 纠错降到 M(33 模块)只省 11% 模块数,容错却从 25% 掉到 15%,不划算; PNG 只能保住原图,缩到 480 一样解不出,体积还是 JPEG 的 5 倍。 - QRCodeSize 165 → 190(37 模块取整为 5px/模块;生产短域名 33 模块为 165px) - QRCardH 315 → 335 容纳变高的二维码,卡片整体仍垂直居中 - 新增 TestGenerateQRModuleSizeAtLeast5:三种常见链接长度下模块必须 ≥5px, 把 QRCodeSize 改回 165 立刻 FAIL 渲染成本基准(1x vs 2x):JPEG 编码 12 → 48ms、背景 Lanczos 缩放 25 → 41ms、 画布分配 3 → 13ms,二维码生成本身 0.8ms —— 2x 的代价主要在编码与缩放, 与二维码尺寸无关,所以放大二维码不增加任何 CPU。
This commit is contained in:
@@ -228,6 +228,31 @@ func TestGenerateQRIsModuleAligned(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// 模块像素是扫码能力的唯一硬指标:实测 5px/模块的卡缩到 320 宽仍可解码,
|
||||
// 4px 时缩到 480 就解不出。这里锁住常见链接长度下的模块尺寸。
|
||||
func TestGenerateQRModuleSizeAtLeast5(t *testing.T) {
|
||||
for _, url := range []string{
|
||||
"https://box.shiroko.one/_/tamakyi",
|
||||
"https://box-dev-api.337845818.best/_/tbunread1022181904",
|
||||
"https://box.shiroko.one/_/a-rather-long-handle-name",
|
||||
} {
|
||||
img, err := generateQR(url, nil, QRCodeSize)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
probe, err := qrcode.New(url, qrcode.High)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
probe.DisableBorder = true
|
||||
mods := len(probe.Bitmap())
|
||||
if per := img.Bounds().Dx() / mods; per < 5 {
|
||||
t.Errorf("%s: %d modules in %dpx -> %dpx/module, want >=5",
|
||||
url, mods, img.Bounds().Dx(), per)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 视觉自检:TEST_PREVIEW=1 时把链接区渲成 PNG,人工确认断行与对齐。
|
||||
func TestShareCardLinkPreview(t *testing.T) {
|
||||
if os.Getenv("TEST_PREVIEW") == "" {
|
||||
|
||||
Reference in New Issue
Block a user