在 C# 中创建、加载和读取 SVG 文件

本指南介绍如何使用 Aspose.SVG for .NET 在 C# 中创建、加载和读取 SVG 文件。您将学习如何从空文档、字符串内容、stream、本地文件、URL 初始化 SVGDocument,以及如何异步加载带有外部资源的 SVG 文档。

SVGDocument 类是使用 Aspose.SVG for .NET 处理 SVG 内容的入口点。它表示 SVG DOM 层次结构的根,保存整个文档内容,并遵循 W3C SVG 2.0WHATWG DOM 规范。

SVG 文件可以通过以下方式创建和加载:

以下 C# 示例演示最常见的 SVGDocument 构造函数和加载场景。

快速开始:在 C# 中创建 SVG 文档

创建 SVG 文档最快的方法是将 SVG 标记作为字符串传递给 SVGDocument 构造函数。当应用程序动态生成 SVG 内容时,这种方式很有用:

1using Aspose.Svg;
2...
3
4    string svgContent = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"100\" height=\"100\"><circle cx=\"50\" cy=\"50\" r=\"40\" /></svg>";
5
6    using (SVGDocument document = new SVGDocument(svgContent, "."))
7    {
8        document.Save("circle.svg");
9    }

创建空 SVG 文档

Aspose.SVG for .NET API 提供 SVGDocument 类,可使用其默认构造函数创建空文档。创建文档对象后,可以稍后用 SVG 元素填充它。以下 C# 代码片段演示如何使用默认 SVGDocument() 构造函数创建 SVG 文档。

1using Aspose.Svg;
2...
3
4    // Initialize an empty SVG document
5    using (SVGDocument document = new SVGDocument())
6    {
7        // Work with the SVG document here...
8    }

如果要将创建的空 SVG 文档保存到文件,请使用以下 C# 代码片段:

1using Aspose.Svg;
2using System.IO;
 1// Create an empty SVG document using C#
 2
 3// Prepare an output path to save a document
 4string documentPath = Path.Combine(OutputDir, "empty.svg");
 5
 6// Initialize an empty SVG document
 7using (SVGDocument document = new SVGDocument())
 8{
 9    // Work with the SVG document here...
10
11    // Save the document to a file
12    document.Save(documentPath);
13}

有关保存 SVG 文件的更多信息,请参阅 保存 SVG 文档 部分。在 编辑 SVG 文件 一文中,您将学习如何使用 Aspose.SVG for .NET 库编辑 SVG,并查看向 SVG 文档添加新元素以及将 SVG 滤镜应用于位图的详细示例。

从内存字符串创建 SVG

当 SVG 标记已存在于内存中时,例如由应用程序生成,或从数据库、API、用户输入接收后,请使用 SVGDocument(string, string) 构造函数。

第二个构造函数参数是基础 URI。Aspose.SVG 使用它解析 SVG 内部的相对路径,例如链接的图像、CSS 文件或字体。如果 SVG 标记不引用外部资源,可以像上面的快速开始示例一样传入 "."。如果引用了外部资源,请传入这些资源所在的文件夹或 URL:

 1using Aspose.Svg;
 2using System.IO;
 3...
 4
 5    // SVG markup contains a relative reference to an external image
 6    string documentContent = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"200\" height=\"120\"><image href=\"images/logo.png\" width=\"200\" height=\"120\" /></svg>";
 7
 8    // Relative paths in the SVG are resolved against this base URI
 9    string baseUri = Path.Combine(DataDir, "assets") + Path.DirectorySeparatorChar;
10
11	// Initialize an SVG document from a string content
12	using (SVGDocument document = new SVGDocument(documentContent, baseUri))
13	{
14	    // Work with the document here...
15	}

从 stream 加载 SVG

要从 stream 加载 SVG,请使用接受 Stream 对象的 SVGDocument() 构造函数之一。此模式适用于从用户上传的文件、嵌入资源、内存缓冲区或其他非文件来源读取 SVG:

 1using Aspose.Svg;
 2using System.IO;
 3...
 4
 5    //Prepare a path to a file required for a FileStream object creating
 6    string documentPath = Path.Combine(DataDir, "bezier-curves.svg");
 7
 8	// Create a FileStream object
 9	using (FileStream stream = new FileStream(documentPath, FileMode.Open, FileAccess.Read))
10	{
11	    // Initialize an SVG document from the stream
12		using (SVGDocument document = new SVGDocument(stream, "."))
13	    {
14	        // Work with the document
15	    }
16	}

使用 SVG Builder API 创建自定义 SVG 文档

SVG Builder API 提供了一种强大而灵活的方式,可通过编程方式构建 SVG 文档。借助 SVGSVGElementBuilder 类,开发人员可以创建带有详细自定义选项的复杂 SVG 图形。有关更多信息,请参阅 使用 Aspose.SVG Builder API 进行高级 SVG 创建和修改

下面的示例演示如何创建包含多种图形元素的自定义 SVG 文档:

1using System.IO;
2using Aspose.Svg;
3using Aspose.Svg.Builder;
4using System.Drawing;
 1// Create SVG using Builder API
 2
 3// Initialize an SVG document
 4using (SVGDocument document = new SVGDocument())
 5{
 6    // Create an <svg> element with specified width, height and viewBox, and add into it other required elements
 7    SVGSVGElement svg = new SVGSVGElementBuilder()
 8        .Width(100).Height(100)
 9        .ViewBox(-21, -21, 42, 42)
10        .AddDefs(def => def
11            .AddRadialGradient(id: "b", cx: .2, cy: .2, r: .5, fx: .2, fy: .2, extend: ev => ev
12                .AddStop(offset: 0, stopColor: Color.FromArgb(0xff, 0xff, 0xFF), stopOpacity: .7)
13                .AddStop(offset: 1, stopColor: Color.FromArgb(0xff, 0xff, 0xFF), stopOpacity: 0)
14            )
15            .AddRadialGradient(id: "a", cx: .5, cy: .5, r: .5, extend: ev => ev
16                .AddStop(offset: 0, stopColor: Color.FromArgb(0xff, 0xff, 0x00))
17                .AddStop(offset: .75, stopColor: Color.FromArgb(0xff, 0xff, 0x00))
18                .AddStop(offset: .95, stopColor: Color.FromArgb(0xee, 0xee, 0x00))
19                .AddStop(offset: 1, stopColor: Color.FromArgb(0xe8, 0xe8, 0x00))
20            )
21        )
22        .AddCircle(r: 20, fill: "url(#a)", stroke: Color.FromArgb(0, 0, 0), extend: c => c.StrokeWidth(.15))
23        .AddCircle(r: 20, fill: "b")
24        .AddG(g => g.Id("c")
25            .AddEllipse(cx: -6, cy: -7, rx: 2.5, ry: 4)
26            .AddPath(fill: Paint.None, stroke: Color.FromArgb(0, 0, 0), d: "M10.6 2.7a4 4 0 0 0 4 3", extend: e => e.StrokeWidth(.5).StrokeLineCap(StrokeLineCap.Round))
27        )
28        .AddUse(href: "#c", extend: e => e.Transform(t => t.Scale(-1, 1)))
29        .AddPath(d: "M-12 5a13.5 13.5 0 0 0 24 0 13 13 0 0 1-24 0", fill: Paint.None, stroke: Color.FromArgb(0, 0, 0), extend: e => e.StrokeWidth(.75))
30        .Build(document.FirstChild as SVGSVGElement);
31
32    // Save the SVG document
33    document.Save(Path.Combine(OutputDir, "face.svg"));
34}

此代码片段创建了一个具有复杂设计的 SVG 文档,展示了 SVG Builder API 以编程方式生成自定义 SVG 图形的灵活性和能力。在上面的 C# 代码中,我们创建了一个包含圆、椭圆、路径和渐变等元素的 SVG 文档。生成的 SVG 图像表示一张微笑的脸:

笑脸 – 一张微笑的脸 – face.svg 文件的渲染结果

从本地文件加载 SVG

要从文件 bezier-curves.svg 加载 SVG,请使用 SVGDocument 类的默认构造函数,并将文件路径作为输入参数传递给它。

 1using Aspose.Svg;
 2using System.IO;
 3...
 4    
 5    // Prepare a path to a file loading
 6    string documentPath = Path.Combine(DataDir, "bezier-curves.svg"); 
 7	
 8	// Load an SVG document from the file
 9	using (SVGDocument document = new SVGDocument(documentPath))
10	{
11	    // Work with the document 
12	}

从 Web 加载 SVG

您也可以直接从 URL 加载 SVG。以下示例展示如何从指向 SVG 文件的 Web 地址创建 SVGDocument

1using Aspose.Svg;
2...
3
4    // Load SVG from the Web at its URL
5    Url documentUrl = new Url("https://docs.aspose.com/svg/files/owl.svg");
6    using (SVGDocument document = new SVGDocument(documentUrl))
7    {
8        // Work with the SVG document here...
9    }
1using Aspose.Svg;
2...
3
4    // Load SVG from the Web at its URL
5    using (SVGDocument document = new SVGDocument(new Url("https://docs.aspose.com/svg/files/basic-shapes.svg")))
6    {
7        // Work with the SVG document here...
8    }

如果设置了无法访问的错误 URL,库会抛出带有专用代码 NetworkErrorDOMException,以提示无法找到所选资源。

异步加载带有外部资源的 SVG

如果 SVG 文档引用外部资源,例如图像、字体、CSS 文件或脚本,加载可能需要额外时间,并可能阻塞应用程序主线程。在异步加载模型中,可以订阅 LoadReadyStateChange 事件,并在 SVG 文档及其资源准备就绪时通知应用程序。

SVGDocument 类的 Navigate(Url) 方法会将指定 URL 中的文档加载到当前实例。

1using Aspose.Svg;
2using System.Threading;
 1// Load SVG asynchronously using C#
 2
 3Url documentUrl = new Url("https://docs.aspose.com/svg/files/owl.svg");
 4ManualResetEvent documentEvent = new ManualResetEvent(false);
 5
 6SVGDocument document = new SVGDocument();
 7
 8// Subscribe to the event 'OnReadyStateChange' that will be fired once the document is completely loaded
 9document.OnReadyStateChange += (sender, ev) =>
10{
11    if (document.ReadyState == "complete")
12    {
13        // Sets the state of the event to signaled to unblock the main thread
14        documentEvent.Set();
15    }
16};
17
18// Load an SVG document Async
19document.Navigate(documentUrl);
20
21// Blocks the current thread while the document is loading
22documentEvent.WaitOne();
23
24// Work with the document

您可以从 GitHub 下载完整示例和数据文件。有关从 GitHub 下载并运行示例的信息,请参阅 如何运行示例 部分。

FAQ

1. 为什么从字符串或 stream 创建 SVG 时,图像、字体或 CSS 文件没有加载?
从字符串或 stream 创建 SVG 时,相对资源路径会根据传递给 SVGDocument 构造函数的基础 URI 进行解析。如果链接的图像、字体或 CSS 文件未加载,请检查基础 URI 是否指向这些资源所在的文件夹或 URL。

2. 如果 SVG 文件包含无效标记,会发生什么?
Aspose.SVG 会将 SVG 作为基于 XML 的内容进行解析。如果标记格式错误,或无法解析所需资源,则文档加载或后续处理可能失败。请验证生成的 SVG 标记,并在生产代码中处理加载异常。

3. 加载后可以修改 SVGDocument 吗?
可以。加载 SVG 文件后,可以遍历和修改其 DOM、添加或删除元素、更新属性、应用样式并保存结果。有关详细编辑示例,请参阅 编辑 SVG 文件 一文。

4. SVGDocument 适合服务器端应用程序吗?
是的。Aspose.SVG for .NET 可用于后端服务、ASP.NET 应用程序、批处理程序和文档自动化工作流,无需依赖浏览器自动化。

5. SVG Builder API 与 DOM 操作有什么区别?
SVG Builder API 适合在 C# 中逐步创建新的 SVG 结构。DOM 操作更适合处理已加载的 SVG 文档,并需要更改其现有元素、属性或样式的场景。

后续步骤