SVG字体、外链图片和filter导出失败的原因与修复方法

Jack

有些 SVG 在设计工具里看起来完全正常,一转成 PNG 就出问题:字体变了,图片区域空白,阴影被切掉,模糊效果不见了,mask 失效,甚至整个图形位置都不对。

这类问题的根本原因是:SVG 不一定是一个完全自包含的图片文件。它可能依赖本机字体、远程图片、外部 CSS、滤镜、遮罩、裁切路径和浏览器渲染能力。转换工具无法访问或复现这些依赖时,导出的 PNG 就会和预览不一致。

下面按最常见的几类问题排查。

SVG显示问题概览
SVG显示问题概览

> 问题1:字体丢失或变成别的字体

SVG 里的文字可能是这样的:

<text font-family="Inter" font-size="32">Export</text>

这行代码并不包含 Inter 字体本身,只是告诉渲染器“请使用 Inter”。如果导出环境里没有这个字体,或者远程字体加载失败,就会被替换成默认字体。结果可能是字距变了、字重变了、文字换行了,甚至被裁切。

怎么修复

品牌关键文字转轮廓。 如果是 Logo、徽章、标题图、固定海报,建议在 Figma、Illustrator、Sketch 或 Inkscape 里把文字转为路径。这样导出 PNG 时就不依赖字体文件。

需要可编辑时再保留文字。 如果这个 SVG 以后还要编辑,或者网页中需要真实文本,可以保留文字,但要确保字体能稳定加载。

尽量不要依赖用户本机字体。 你电脑上有的字体,转换环境或访问者设备上不一定有。

对于最终只需要 PNG 的图形,文字转轮廓通常是最稳的处理方式。

> 问题2:外链图片不显示

SVG 可以引用外部图片:

<image href="photo.png" width="400" height="300" />

也可以引用远程地址:

<image href="https://example.com/photo.png" />

如果转换工具拿不到这张图片,导出的 PNG 里对应区域就会空白。

常见原因包括:

  • SVG 文件被单独上传,旁边的图片文件没有一起带上
  • 相对路径在新位置失效
  • 远程服务器禁止跨域访问
  • 图片地址需要登录
  • 临时图片链接过期
  • 图片被移动或删除

怎么修复

如果图片很重要,建议把它嵌入 SVG,变成 data URL:

<image href="data:image/png;base64,..." />

这样 SVG 文件会变大,但它会成为一个完整文件,不再依赖外部路径。对于隐私文件、本地转换、发给别人处理的 SVG,这种方式更可靠。

如果必须保持外链,就要保证文件夹结构不变,并在最终环境里重新打开 SVG 检查。

> 问题3:filter效果不一致或被裁切

SVG 的 filter 可以实现阴影、模糊、颜色变换、发光等效果。但不同浏览器和转换工具对复杂滤镜的支持并不完全一致。

常见现象:

  • 阴影被画布边缘切掉
  • 模糊半径和设计稿不同
  • 颜色滤镜偏色
  • 复杂滤镜消失
  • 导出速度很慢或失败

阴影被裁切通常是因为滤镜区域太小:

<filter id="shadow" x="0" y="0" width="100%" height="100%">

阴影超出这个区域后就会被裁掉。可以扩大滤镜区域:

<filter id="shadow" x="-20%" y="-20%" width="140%" height="140%">

如果是用于生产环境的导出,尽量简化复杂滤镜。普通阴影和模糊通常比较稳定,叠加很多层的混合模式、位移滤镜、光照滤镜更容易出差异。

> 问题4:mask和clipPath失效

头像、徽章、图表、插图里经常用到 maskclipPath。它们失效时,图片可能不裁切、裁切错位置,或者整个区域消失。

重点检查:

  • 多个 SVG 合并后是否出现重复 id
  • clipPathmask 引用的 ID 是否存在
  • mask 内部是否引用外部图片
  • 被裁切对象是否被 transform 移到了画布外
  • viewBox 是否和实际图形范围匹配

如果 SVG 在浏览器里直接打开就不正常,说明文件结构本身有问题。如果浏览器正常、某个转换工具不正常,建议在设计工具里把效果扁平化后再导出。

> 问题5:外部CSS没有一起导出

有些 SVG 依赖外部样式:

<link rel="stylesheet" href="styles.css" />

或者使用外部定义的 class:

<path class="brand-primary" />

如果 CSS 没有包含在 SVG 文件里,转换工具就不知道这个路径应该是什么颜色、什么描边、什么字体。

更适合转换的写法是把关键样式内联:

<path fill="#0f766e" stroke="#0f172a" stroke-width="2" />

这不一定是最优雅的代码组织方式,但对 SVG 转 PNG 来说更稳定。

> 导出前准备清单

重要文件转换前,建议先做这些处理:

  • Logo 和标题文字转轮廓。
  • 重要外链图片改为嵌入。
  • 减少远程字体、远程图片和外部 CSS 依赖。
  • 把关键颜色、描边、透明度写进 SVG。
  • 阴影和模糊扩大 filter 区域。
  • 检查 mask、clipPath 的 ID 是否重复或缺失。
  • 确认 viewBox 正确。
  • 批量转换前先测试一个样本。

使用 svg2img.cc 时,转换在浏览器本地完成,文件不会上传到服务器。这对隐私是好事,但也意味着浏览器只能渲染它能访问到的资源。自包含 SVG 比依赖远程资源的 SVG 更适合转换。

> 什么时候应该扁平化

如果最终只需要 PNG,不需要继续编辑 SVG,扁平化通常是最省事的方案:文字转路径、图片嵌入、复杂效果简化、从固定画板导出。

可编辑 SVG 适合后续维护;扁平化 SVG 适合稳定导出。你越能减少外部依赖,导出的 PNG 就越可预测。