先把结论钉在字节上
这一页的产物里没有 <path>,只有 <image> 那一行把整条 data URL 原样抱住。全模板 grep canvas、drawImage、toDataURL、trace、quantiz、posterize 各 0 次,位图入口只有 readAsDataURL 的 1 次(L144)。28 张自造图加同批另外 3 张共 31 个文件,取回 base64 解码后与输入逐字节 31/31 全等。
被测的是图片转 SVG那页的模板,10270 字节,脚本段逐字摘进 node:vm 原样跑。
容器开销是一个常数
buildSvg(L157–L198)的固定部分是 15 段字面量相加:39+40+48+12+10+2+18+1+3+16+10+2+21+4+6 = 232 字节,含 7 枚换行、27 枚缩进空格。于是 svgB = 232 + 3*len(w) + 3*len(h) + prefixLen + b64Len:w、h 各写三遍,每个数字字符付 3 字节;prefixLen 只有 22 与 23。31 行容器恒等式表 resid 全 0,例 n=581743 的 jpg:775660 + 21 + 23 + 232 = 775936。
base64 只报对账结果
ceil(n/3)*4 命中 31/31;补位三档,余 0 尾下 0 枚(28 张里 8 张)、余 1 补 2 枚(12 张)、余 2 补 1 枚(8 张)。整除样本的 b64/n 正好 1.333333,偏离只在几十上百字节量级看得见:a_1x1.png 是 1.369863,到 100 KB 级只剩 0.000025。
从不生效的「base64 嵌入」
L21 那枚 checkbox 全文出现 1 次、出厂 checked,脚本块里按 id 取它 0 次。对 d_101x67.png 把勾选切成三态各构建一次,三次产物 sha 前 12 位都是 5d037f0d8a4b、长度都是 30249,取消勾选后输出逐字节不变。L22 那句「使用 base64 嵌入(生成独立 SVG 文件)」在本页没有落点,因为这一页唯一的嵌入方式就是 base64。
图 1:同一条链上的三层长度。
四档缩放只改三个声明数字
L159/L160 的 Math.round 只产出 6 个数字槽,L168 的 base64 与档位无关。那张 24 行的缩放表里,241×137 的 b64Len 恒 142064,声明依次 60×34、121×69、241×137、482×274;101×67 的 PNG 恒 29980、BMP 恒 27232。取整痕迹 120.5 → 121、60.25 → 60;1×1 选 25% 归零成 width="0" height="0" 与 image_0x0.svg。
| 档位 | 声明 w×h | svgB | 界面「SVG 大小」 |
|---|---|---|---|
| 25% | 60×34 | 142330 | 139.0 KB |
| 50% | 121×69 | 142333 | 139.0 KB |
| 100% | 241×137 | 142336 | 139.0 KB |
| 200% | 482×274 | 142336 | 139.0 KB |
档间那 6 字节差只来自位数变化,位图数据一动不动。
标签会停在旧档位
出厂三处口径互不相同:L26 的 active 在 25%、L85 默认 imgSvgScale=100、档位标签出厂写 100%。上传后 L131–L134 重置 scale=100、active 移到下标 2,却不碰标签文本——全文给这个 id 赋值的只有 L152。实测先点 25% 再上传另一张,标签停在 "25%"、实际 imgSvgScale=100、声明与固有都是 241×137,即按 100% 出图而界面写着 25%。
下载 URL 的第二次膨胀
L171 的 encodeURIComponent 只动 base64 里的加号、斜杠、等号,每枚从 1 字符变 3 字符。合式 urlLen = 33 + svgB + 2*esc 在那张 18 行表上全 OK,骨架固定贡献 100 枚被转义字符。urlLen/svgB 从 1.6694 收敛到 1.0552,大文件稳定在 1.055 到 1.072;h_1200x900.png 因斜杠占 4.5669%、加号占 2.6251% 被推到 1.1440。预览与下载吃这一层,界面显示的是上一层。
显示口径与格式判定
formatSize(L226–L230)先判档再 toFixed(1),于是 1048575 显示成 1024.0 KB,h_1200x900.png 相邻两行一个 1006.3 KB、一个 1.3 MB——这是本页显示口径,不是文件系统差异。
L103 那个正则 /image\// 无锚点、无 i 标志,17 个 type 放行 11 条、拦截 6 条:拦下空串、text/plain、application/pdf、IMAGE/PNG、png、image,而 ximage/png、foo/image/bar、not/image/、text/html,image/png 全过,「格式」行显示成 XPNG、FOO/BAR、NOT/、TEXT/HTML,PNG。grep onerror 0 次,解码失败时整段不执行、面板不亮。
动图与文案对照
j_anim2.gif(900 字节、loop=0)两帧延迟 20cs 与 50cs,封装后解回字节重解帧结构逐字段相同、MIME 仍是 image/gif,svgB 1472。0 尺寸 SVG 的渲染、Chrome 同名追加 (1)、data URL 长度上限、6.4 MB 进 innerHTML 的代价连同逐帧播放都未实测,原因是 Node 无渲染与下载栈;JPG 与 WEBP 的字节流由 headless Chrome 代编码并回核过前缀与长度。文案按 config/tools.php 第 46 个条目判 17 句:一致 6、需限定与部分一致 4、冲突 7,其中 5 句指着同一处代码事实。
封装与描摹的分界,旧文位图转矢量写过,不复述;容器之间的搬运归 SVG 格式转换,本文对它没有测量。
常见问题
Q:取消「base64 嵌入」勾选,产物会变吗?
不会,三态产物的 sha 前 12 位与长度 30249 全同。
Q:选 25% 之后文件会小一点吗?
241×137 四档的 b64Len 恒 142064,svgB 只差 6 字节,界面都是 139.0 KB。
Q:GIF 动图封进去保得住吗?
字节与帧结构保得住,延迟 20cs 与 50cs 反解后逐字段相同;播放体验未实测。