预览里有 3 张图,成品只剩 1 张
起点是一份 sv_image_rel.svg:594 B,3 个 <image>,两条用相对路径外链同一张 64×64 瓦片,第三条 data: URI 内嵌。预览里三张都在,探针记到 3 次 load;转成 PNG 拿回来的成品 2576 B,外链区墨迹 px=0,只剩内嵌那条的 4096 px。差的是两套加载机制。
内联 DOM 与 Blob→Image→drawImage
把文件交给SVG转换格式之后,「加载」与「转换并下载」是两段不相交的链路。预览侧(行 121-168):DOMParser 解析字符串,取第一个 <svg> 内联进文档,不建 Image 也不建 Blob URL,外链按普通网页资源去取。导出侧(行 200-255):字符串→Blob→objectURL→new Image→onload 后 drawImage 进 canvas。按图片解码时文档是 opaque origin,内部引用另算,分岔从这里来。
四类内部依赖,两侧读数不同
跨文件 <use>(249 B)在 DOM 侧触发了 load,栅格侧整幅 px=0。外链 @import(284 B)给 64px 文本定的规则没生效,computed 回落成 -apple-system、14px,长度读数 85.83;同一条规则内联(332 B)读数是 475.06。成品侧同样分裂:外链那份导出 4972 B 的 PNG,墨迹只有 692 px。
外链 @font-face(322 B)与同一字体 data: 内嵌(612547 B)在 DOM 列同宽,读数都是 400.55;栅格列却是 px=5401、bbox 315×49 对 px=4855、314×43。fill:url(外链图) 那份 256 B:DOM 里 fill 计算值原样带着 url,栅格侧整幅 px=0,成品 2544 B 是张纯空图,toast 照样报成功。
这些不能写成「外链依赖实测不支持」。本机 Chrome 带 --allow-file-access-from-files 启动,改成 file:/// 与 https:// 绝对外链的两份样张,导出时反而都进了栅格,ink px=3327,成品同为 8075 B。能写的只有:预览与导出两条路径的墨迹不同,无头环境未能触发拦截,不外推线上口径。
图 1 四类内部依赖在两条路径下的读数
两个尺寸框与 viewBox 的成对覆盖
convert-out-w / convert-out-h 写的是画布像素,与 SVG 自身只在「原始尺寸」一步有关:viewBox 存在且 split 出 4 段、宽或高缺位时,两值成对被它的第 3、4 段顶掉;两个属性都写时 viewBox 不参与;导出侧只读框。max="10000" 只是 HTML 属性,代码不读——等比勾选下高打 10000,宽被反算成 13333 写进框;探针写 100000 也原样回读、报错位 null。
| svg 根上的写法 | 两框读数 | 取哪一边 |
|---|---|---|
| 只有 viewBox="0 0 320 240" | 320 × 240 | 缺位时 viewBox 顶上来 |
| width="100" + viewBox | 320 × 240 | 写进去的 100 被成对丢掉 |
| width="320" height="240" + viewBox="0 0 100 50" | 320 × 240 | 两个都在,viewBox 不参与 |
取整方向也不统一:origin 与等比反算用 Math.round,导出取值用 parseInt,同一个框里 "333.7" 截成 333、"1e3" 截成 1;写 0 或留空是假值,退回 origin。
超画布上限,静默交出空载荷
16385×16385 与 20000×20000 时 data URL 只剩 6 字符,载荷就是 "data:,";toast 仍是「已转换为 PNG (20000×20000) 并开始下载」。上限之内是真字节:320×240 基准图出 35990 B,6000×6000 是 697011 B,10000×10000 是 1889260 B,魔数全是 89 50 4e 47 0d 0a 1a 0a。
字宽账:栅格一律裁到 320
"VECTOR-0123" @64,在 12 个 font-family 下的 DOM 长度读数从 352.00(monospace 与宋体)排到 484.97(Arial Black),差 132.97;族名不存在不报错,落回继承那档 392.44。DOM 里的 rect 还要再乘预览缩放,预览因此看着合适;320 宽的画布则把栅格墨迹一律裁到 ≤320。
图 2 族名字宽谱,与 320 宽画布的竖直上限
单次处理与 object URL 回收
这一页没有批量入口:fileInputMultiple=false,拖拽与 change 两处(行 104、107)都只取 files[0]。整轮 13 步测得 object URL made=11 / revoked=11,一次导出 1 造 1 销,没有累积。「该转多大、存成什么格式」是另一笔账,SVG 转 PNG 的导出尺寸与格式选择那篇已经拆过,不复述。
几个常见追问
Q:预览和成品对不上,先查哪里?
查 SVG 里指向外部的引用:<image> 相对路径、跨文件 <use>、外链 @import / @font-face、fill:url(...)。它们都活在 DOM 里、栅格化时另算。
Q:框里写大数没报错,是不是就安全?
不是。max 属性与报错位都拦不住写入,13333 照样进框;越过画布上限也只有 6 字符空载荷配成功 toast,得自己核对成品字节与魔数。
Q:成品文字比预览窄?
font-family 依赖本机字体,12 族读数能差 132.97;320 宽画布再把栅格一律裁到 ≤320。要稳:导出前把规则内联、字体以 data: 内嵌。