perf: 体积从 105.1 MB 降到 28.9 MB(音频转 Opus、图片无损 WebP)
- 两首 flac 母带移入 masters/(gitignore,不入库),转 Opus 128k VBR:3.35 + 3.16 MB - xilian 三张真 PNG RGBA → 无损 WebP(3.39→1.80、5.01→2.83、3.38→1.76 MB) - kv37_xilian.png → 无损 WebP 5.13→2.75 MB - kv37 五张图本来就是 WebP(扩展名误写成 .png),本次只改名并把 atlas 页名改为 .webp - 删除死文件 dist/jsconfig.json - 新增 tools/rawdiff.mjs(区分可见差异与仅透明下差异)、tools/atlas-pages.mjs 验证:check-paths 11/11;0 个非 favicon 的 404;无损 WebP 可见像素 0 差异; libwebp 会改写完全透明像素下的 RGB(xilian 三图 32-49% 像素),渲染级对拍 与 PNG 版相差 0.052/255、热力图全空,确认未因 Linear 过滤渗色。
This commit is contained in:
1 parent
8ad177c822
commit
a391021041
27 files changed
+3006
-2879
No files matched your search
@@ -0,0 +1,70 @@
|
||||
// 逐像素比对两张图(解码成 RGBA 后比),并且区分"差异是否只发生在完全透明的像素下"。
|
||||
// 这个区分很关键:本项目依赖"A=0 处 RGB 已清零",因为贴图是 Linear 过滤,
|
||||
// 透明像素的 RGB 会在线性插值时渗进边缘像素——所以"仅在 A=0 处不同"的转码仍然是不可接受的。
|
||||
// 用法:node tools/rawdiff.mjs <a> <b>
|
||||
|
||||
import { spawn } from "node:child_process";
|
||||
|
||||
function decode(file) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const p = spawn("ffmpeg", ["-v", "error", "-i", file, "-f", "rawvideo", "-pix_fmt", "rgba", "-"], {
|
||||
stdio: ["ignore", "pipe", "pipe"],
|
||||
});
|
||||
const chunks = [];
|
||||
let err = "";
|
||||
p.stdout.on("data", (d) => chunks.push(d));
|
||||
p.stderr.on("data", (d) => (err += d));
|
||||
p.on("close", (code) => (code === 0 ? resolve(Buffer.concat(chunks)) : reject(new Error(err || `exit ${code}`))));
|
||||
});
|
||||
}
|
||||
|
||||
const [a, b] = process.argv.slice(2);
|
||||
if (!a || !b) {
|
||||
console.error("usage: node tools/rawdiff.mjs <a> <b>");
|
||||
process.exit(2);
|
||||
}
|
||||
|
||||
const [da, db] = await Promise.all([decode(a), decode(b)]);
|
||||
if (da.length !== db.length) {
|
||||
console.log(`尺寸/格式不同:${da.length} vs ${db.length} 字节`);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const px = da.length / 4;
|
||||
let diffAny = 0;
|
||||
let diffHidden = 0; // 仅因为 A=0 而不可见
|
||||
let diffVisible = 0;
|
||||
let maxVisible = 0;
|
||||
let maxHidden = 0;
|
||||
|
||||
for (let i = 0; i < da.length; i += 4) {
|
||||
const dr = Math.abs(da[i] - db[i]);
|
||||
const dg = Math.abs(da[i + 1] - db[i + 1]);
|
||||
const db_ = Math.abs(da[i + 2] - db[i + 2]);
|
||||
const dA = Math.abs(da[i + 3] - db[i + 3]);
|
||||
const m = Math.max(dr, dg, db_, dA);
|
||||
if (!m) continue;
|
||||
diffAny++;
|
||||
if (dA === 0 && da[i + 3] === 0) {
|
||||
diffHidden++;
|
||||
if (m > maxHidden) maxHidden = m;
|
||||
} else {
|
||||
diffVisible++;
|
||||
if (m > maxVisible) maxVisible = m;
|
||||
}
|
||||
}
|
||||
|
||||
const pct = (n) => ((n / px) * 100).toFixed(4) + "%";
|
||||
console.log(`${a} vs ${b}`);
|
||||
console.log(` 总像素 ${px}`);
|
||||
console.log(` 有差异像素 ${diffAny} (${pct(diffAny)})`);
|
||||
console.log(` 可见差异 ${diffVisible} (${pct(diffVisible)}) 最大通道差 ${maxVisible}`);
|
||||
console.log(` 仅透明下差异 ${diffHidden} (${pct(diffHidden)}) 最大通道差 ${maxHidden}`);
|
||||
console.log(
|
||||
diffAny === 0
|
||||
? " 结论: 逐像素相同"
|
||||
: diffVisible === 0
|
||||
? " 结论: 只在完全透明像素下有差异——渲染仍可能因 Linear 过滤在边缘渗色,不算安全"
|
||||
: " 结论: 可见像素被改动",
|
||||
);
|
||||
process.exit(diffVisible === 0 && diffAny === 0 ? 0 : 1);
|
||||
Reference in new issue
Block a user