SVG 嵌入内容 – 图像、嵌套 SVG 和 HTML

SVG embedded content 指在 SVG 标记中引用或包含非基础绘图内容,例如栅格图像、另一个 SVG 文件或 HTML 标记。当你构建图表、报告、徽章、信息图、预览图或导出图形,并需要把矢量形状与徽标、照片、截图或格式化文本块结合起来时,这个主题非常重要。

快速回答: 使用 SVG <image> 元素可以把 PNG、JPG、GIF、WebP 或另一个 SVG 放入 SVG 文档。需要在 SVG 中放置 HTML 标记时,使用 <foreignObject>。始终设置 xywidthheight,用 preserveAspectRatio 控制缩放,并确保 SVG 被打开、渲染或转换时可访问外部资源。

1<svg width="300" height="180" xmlns="http://www.w3.org/2000/svg">
2  <image href="logo.png" x="20" y="20" width="120" height="120" />
3</svg>

SVG 嵌入内容基础

SVG 不限于 paths、形状和文本。它也可以包含来自其他格式的内容。最常见的两个元素是:

元素适用场景重要说明
<image>PNG、JPG、GIF、WebP 等栅格图像,以及作为图像资源使用的另一个 SVG需要 widthheight;外部文件必须可访问
<foreignObject>SVG 区域内的 HTML 或其他 XML 内容需要正确的命名空间,在某些渲染流程中支持可能受限

当源内容应保持为图像或 HTML 片段时使用嵌入内容。不要把它与矢量化混淆。把 PNG 嵌入 SVG 仍然保留 PNG 像素,并不会把 PNG 转换成 paths。如果需要栅格到矢量描摹,请参见 Convert Image to SVG in C#Vectorize Images in Python

如何在 SVG 中嵌入内容

  1. 对栅格图像或嵌套 SVG 文件使用 <image>,对 HTML 标记使用 <foreignObject>
  2. 设置 xy,把嵌入内容放到 SVG 坐标系统中的指定位置。
  3. 设置 widthheight;缺少它们时,许多渲染器不会显示内容。
  4. 使用 href 指定 <image> 的源文件、URL 或 data URI。
  5. 当源图像需要保持比例时,使用 preserveAspectRatio
  6. 在最终使用环境中测试 SVG,尤其是在转换为 PDF、PNG 或 JPG 之前。

在 SVG 中嵌入图像

SVG <image> 元素把图像资源放入 SVG 坐标系统中的一个矩形 viewport。该资源可以是 PNG 或 JPG 等栅格图像,也可以是作为图像使用的另一个 SVG 文件。

最重要的属性是:

属性用途
x, y图像 viewport 的位置
width, height图像 viewport 的尺寸,通常是渲染所必需的
href图像资源的路径、URL 或 data URI
preserveAspectRatio控制图像是适配、裁剪还是拉伸

下面的示例把一个 PNG 图像和一个外部 SVG 文件嵌入到同一个父 SVG 中。两个图像都使用明确的属性设置位置和尺寸,因此布局是可预测的。

1<svg width="500" height="400" xmlns="http://www.w3.org/2000/svg">
2  <image href="https://docs.aspose.com/svg/images/svg.png" x="20" y="20" width="180" height="180" />
3  <image href="https://docs.aspose.com/svg/files/shapes.svg"
4         x="250" y="10" width="220" height="220"
5         preserveAspectRatio="xMidYMid meet" />
6  <text x="40" y="250">Embedded PNG image</text>
7  <text x="300" y="250">Embedded SVG image</text>
8</svg>

渲染结果显示两个嵌入资源:左侧是 PNG 图像,右侧是 SVG 文件。

使用 SVG image 元素嵌入的 PNG 和嵌套 SVG 图像

外部图像文件与 Data URI 图像

<image> 元素可以引用外部文件、远程 URL 或 Base64 data URI。外部文件让 SVG 更小、更易编辑,但这些文件必须保持可访问。Data URI 让 SVG 更自包含,但会显著增加文件大小,并使标记更难维护。

对于受控网站、文档示例和可编辑项目,优先使用外部文件。当 SVG 必须作为单个文件传递,且嵌入的栅格图像足够小时,再使用 data URI。

1<image href="data:image/png;base64,..." x="0" y="0" width="200" height="120" />

在 SVG 中添加 HTML

<foreignObject> 元素允许 SVG 包含来自另一个 XML 命名空间的标记。在浏览器 SVG 中,常见用途是嵌入小型 HTML 片段。对于格式化标签、富文本块或类似 UI 的注释,这通常比纯 SVG 文本更容易表达。

必需属性包括:

属性用途
x, yforeign object 区域的位置
width, heightHTML 内容可渲染区域的尺寸

<foreignObject> 内部的 HTML 根元素应声明 XHTML 命名空间 http://www.w3.org/1999/xhtml。如果缺少正确命名空间,内容可能无法渲染。为了获得更可靠的渲染,请把 font-sizefont-familyline-heightcolor 等关键文本样式直接放在 XHTML 元素上,或使用你已在目标渲染器中测试过的 CSS 规则。

1<svg width="500" height="400" viewBox="0 0 250 200" xmlns="http://www.w3.org/2000/svg">
2  <circle cx="70" cy="70" r="60" fill="red" fill-opacity="0.1" />
3  <foreignObject x="20" y="40" width="210" height="180">
4    <div xmlns="http://www.w3.org/1999/xhtml"
5         style="color:#555; font-family:Arial, sans-serif; font-size:12px; line-height:1.4;">
6      Convert SVG to PNG, PDF, XPS, and major image formats with Aspose.SVG.
7    </div>
8  </foreignObject>
9</svg>

下图展示了使用 <foreignObject> 在 SVG 区域内渲染的 HTML 文本块。

使用 foreignObject 嵌入 SVG 内部的 HTML 文本块

<foreignObject> 很强大,但它不如基本 SVG 形状和文本那样可移植。一些导出、安全或服务端渲染流程可能限制嵌入内容中的 HTML、CSS、脚本或外部资源。如果 SVG 必须在所有环境中保持一致渲染,优先使用纯 SVG 文本和形状。

Common Mistakes and Fixes

问题原因修复方法
嵌入图像不显示<image> 缺少 widthheight添加明确尺寸来定义图像 viewport
转换后图像消失渲染器无法访问链接文件或远程 URL使用可访问路径,配置资源访问,或把小图像嵌入为 data URI
图像被拉伸缺少 preserveAspectRatio 或设置为 none使用 preserveAspectRatio="xMidYMid meet" 保持比例
<foreignObject> 中的 HTML 不可见XHTML 命名空间错误或缺失在根 HTML 元素上使用 xmlns="http://www.w3.org/1999/xhtml"
不同工具输出不一致<foreignObject> 支持取决于渲染器、CSS 支持或安全上下文需要稳定转换结果时使用纯 SVG 标记,或把关键 HTML 样式写为 inline
SVG 文件过大大型栅格图像被嵌入为 Base64大图保持外部引用,或在嵌入前优化

Quick Recipes

嵌入 PNG 图像

1<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg">
2  <image href="image.png" x="0" y="0" width="200" height="200" />
3</svg>

嵌入外部 SVG 文件

1<svg width="300" height="300" xmlns="http://www.w3.org/2000/svg">
2  <image href="icon.svg" x="10" y="10" width="280" height="280" />
3</svg>

保持图像宽高比

1<svg width="250" height="250" xmlns="http://www.w3.org/2000/svg">
2  <image href="photo.jpg"
3         x="0" y="0"
4         width="250" height="250"
5         preserveAspectRatio="xMidYMid meet" />
6</svg>

添加小型 HTML 标签

1<foreignObject x="20" y="20" width="160" height="80">
2  <div xmlns="http://www.w3.org/1999/xhtml">HTML label</div>
3</foreignObject>

FAQ – SVG 嵌入内容

可以在 SVG 中嵌入 PNG 或 JPG 吗?

可以。使用 <image> 元素,并设置 hrefxywidthheight。栅格图像仍然是 SVG 内部的栅格内容,不会自动转换为矢量 paths。

可以在一个 SVG 中嵌入另一个 SVG 吗?

可以。当你只需要把另一个 SVG 当作图像资源显示时,可以使用 <image href="file.svg"> 引用它。如果需要把嵌套 SVG 的结构作为父文档的一部分进行编辑,应改为内联 SVG 标记。

SVG 可以包含 HTML 吗?

可以,通过 <foreignObject>。嵌入的 HTML 应使用 XHTML 命名空间,并在目标浏览器或渲染器中测试,因为支持情况可能不同。

为什么嵌入图像在 PDF 或 PNG 输出中丢失?

渲染器可能无法访问引用的文件、URL、字体、CSS 或 HTML 内容。转换前请使用稳定资源路径、把小资源嵌入为 data URI,或配置资源访问。

嵌入图像等于把图像转换为 SVG 吗?

不是。嵌入只是把原始栅格图像放进 SVG。转换或矢量化图像则会把像素描摹成 SVG paths 和形状。

相关资源