Aspose.SVG for .NET 24.3.0 – 将 SVG 保存到流

Aspose.SVG for .NET 24.3.0

在版本 24.3.0 中,IOutputStorage 接口和 LocalFileSystemStorage 类已弃用,但在版本 24.6.0 发布之前将继续有效。如果您使用早期版本的 Aspose.SVG for .NET,我们建议您升级并迁移到新版本,因为版本 24.6.0 将删除这些已弃用的类。

DeprecatedNew
IOutputStorage InterfaceResourceHandler Class
LocalFileSystemStorage ClassFileSystemResourceHandler Class

SVG 文档可以包含不同的资源,例如 CSS、外部图像和文件。在本文中,我们将考虑将带有资源的 SVG 文档保存到 Zip 存档、内存流和本地文件系统存储的情况。 Aspose.SVG for .NET 继续开发和增强使用所有链接文件保存 SVG 的方法。在这里,我们将查看使用已弃用的类保存文件的示例,并提供用于实现新类的高级解决方案。

ResourceHandler类对比IOutputStorage接口

ResourceHandler 类允许开发人员实现 HandleResource() 方法,在该方法中您可以自己创建一个流并在需要的地方释放它。新方法增加了查看Resource并处理有关它的更多信息的能力。因此,通过采用ResourceHandler类,开发人员可以从更简化和更具表现力的资源管理方法中受益,从而在保存 SVG 文档时生成更清晰、更易于维护和灵活的代码。

将 SVG 保存到 Zip 存档

在这里,我们将研究一个使用过时的IOutputStorage接口和新的ResourceHandler类将 with-resources.svg 文件保存在 Zip 存档中的示例。

使用 IOutputStorage – 24.2.0 及更早版本

IOutputStorage接口是支持输出流的创建和管理的基本接口。您可以通过创建 ZipStorage 类来实现 IOutputStorage 接口,以将带有资源的 SVG 保存到 Zip 存档中:

 1using System.IO;
 2using Aspose.Svg.IO;
 3using System.IO.Compression;
 4...
 5
 6	// Prepare a path to a source SVG file 
 7    string inputPath = Path.Combine(DataDir, "with-resources.svg");;
 8    
 9    var dir = Directory.GetCurrentDirectory();
10
11    // Prepare a full path to an output Zip storage
12    string customArchivePath = Path.Combine(dir, "./../../../../tests-out/old/archive.zip");
13
14    // Load the SVG document 
15    using (var doc = new SVGDocument(inputPath))
16    {
17        // Initialize an instance of the ZipStorage class
18        using (var zipSrorage = new ZipStorage(customArchivePath))
19        {
20            // Save SVG with resources to a Zip archive
21            doc.Save(zipSrorage);
22        }
23    }

以下代码片段显示了 ZipStorage 类中IOutputStorage的实现,以演示如何将包含资源的 SVG 文档保存到 Zip 存档中。

 1    internal class ZipStorage : IOutputStorage, IDisposable
 2    {
 3        private FileStream zipStream;
 4        private ZipArchive archive;
 5        private int streamsCounter;
 6        private bool initialized;
 7
 8        public ZipStorage(string name)
 9        {
10            DisposeArchive();
11            zipStream = new FileStream(name, FileMode.Create);
12            archive = new ZipArchive(zipStream, ZipArchiveMode.Update);
13            initialized = false;
14        }
15
16        public OutputStream CreateStream(OutputStreamContext context)
17        {
18            var zipUri = (streamsCounter++ == 0 ? Path.GetFileName(context.Uri) :
19                Path.Combine(Path.GetFileName(Path.GetDirectoryName(context.Uri)), Path.GetFileName(context.Uri)));
20            var samplePrefix = String.Empty;
21            if (initialized)
22                samplePrefix = "my_";
23            else
24                initialized = true;
25
26            var newStream = archive.CreateEntry(samplePrefix + zipUri).Open();
27            var outputStream = new OutputStream(newStream, "file:///" + samplePrefix + zipUri);
28            return outputStream;
29        }
30
31        public void ReleaseStream(OutputStream stream)
32        {
33            stream.Flush();
34            stream.Close();
35        }
36
37        private void DisposeArchive()
38        {
39            if (archive != null)
40            {
41                archive.Dispose();
42                archive = null;
43            }
44            if (zipStream != null)
45            {
46                zipStream.Dispose();
47                zipStream = null;
48            }
49            streamsCounter = 0;
50        }
51
52        public void Dispose()
53        {
54            DisposeArchive();
55        }
56    }

使用新的 ResourceHandler 类 – 自版本 24.3.0 起

ResourceHandler 类供客户实现。以下 C# 示例展示了如何使用 ResourceHandlerZipResourceHandler 类将包含资源的 SVG 文档保存到 Zip 存档:

 1using System.IO;
 2using Aspose.Svg.IO;
 3using System.IO.Compression;
 4...
 5
 6    // Prepare a path to a source SVG file 
 7    string inputPath = Path.Combine(DataDir, "with-resources.svg");
 8
 9    var dir = Directory.GetCurrentDirectory();
10
11    // Prepare a full path to an output Zip storage
12    string customArchivePath = Path.Combine(dir, "./../../../../tests-out/new/archive.zip");
13
14    // Load an SVG document 
15    using (var doc = new SVGDocument(inputPath))
16    {
17        // Initialize an instance of the ZipResourceHandler class
18        using (var resourceHandler = new ZipResourceHandler(customArchivePath))
19        {
20            // Save SVG with resources to a Zip archive
21            doc.Save(resourceHandler);
22        }
23    }

以下代码片段显示了 ZipResourceHandler 类中 ResourceHandler 的实现,以演示如何将包含资源的 SVG 文档保存到 Zip 存档。 ZipResourceHandler 类的 HandleResource() 方法负责在创建 Zip 存档时的保存过程中处理每个资源:

 1    internal class ZipResourceHandler : ResourceHandler, IDisposable
 2    {
 3        private FileStream zipStream;
 4        private ZipArchive archive;
 5        private int streamsCounter;
 6        private bool initialized;
 7
 8        public ZipResourceHandler(string name)
 9        {
10            DisposeArchive();
11            zipStream = new FileStream(name, FileMode.Create);
12            archive = new ZipArchive(zipStream, ZipArchiveMode.Update);
13            initialized = false;
14        }
15
16        public override void HandleResource(Resource resource, ResourceHandlingContext context)
17        {
18            var zipUri = (streamsCounter++ == 0
19                ? Path.GetFileName(resource.OriginalUrl.Href)
20                : Path.Combine(Path.GetFileName(Path.GetDirectoryName(resource.OriginalUrl.Href)),
21                    Path.GetFileName(resource.OriginalUrl.Href)));
22            var samplePrefix = String.Empty;
23            if (initialized)
24                samplePrefix = "my_";
25            else
26                initialized = true;
27
28            using (var newStream = archive.CreateEntry(samplePrefix + zipUri).Open())
29            {
30                resource.WithOutputUrl(new Url("file:///" + samplePrefix + zipUri)).Save(newStream, context);
31            }
32        }
33
34        private void DisposeArchive()
35        {
36            if (archive != null)
37            {
38                archive.Dispose();
39                archive = null;
40            }
41
42            if (zipStream != null)
43            {
44                zipStream.Dispose();
45                zipStream = null;
46            }
47
48            streamsCounter = 0;
49        }
50
51        public void Dispose()
52        {
53            DisposeArchive();
54        }
55    }

将 SVG 保存到内存流

让我们考虑使用已弃用的IOutputStorage接口和新的 ResourceHandler 类将带有链接资源的 SVG 文件保存到内存流的 C# 示例。源 with-resources.svg 文档和链接的图像文件位于同一目录中。

使用 IOutputStorage – 24.2.0 及更早版本

IOutputStorage接口实现允许将 SVG 保存到内存流:

 1using System.IO;
 2using Aspose.Svg.IO;
 3using System.Collections.Generic;
 4...
 5
 6    // Prepare a path to a source SVG file
 7    string inputPath = Path.Combine(DataDir, "with-resources.svg");
 8
 9    // Initialaze an SVG document
10    using (var doc = new SVGDocument(inputPath))
11    {
12        // Create an instance of the MemoryOutputStorage class and save SVG to memory
13        var memoryStorage = new MemoryOutputStorage();
14        doc.Save(memoryStorage);
15	    memoryStorage.PrintInfo();
16    }

示例运行后,将打印有关内存存储的消息:

uri:memory:///with-resources.svg, length:556
uri:memory:///photo.png, length:57438

以下代码片段显示了 MemoryOutputStorage 类中IOutputStorage的实现,以演示将 SVG 文档保存到内存流。

 1    internal class MemoryOutputStorage : IOutputStorage
 2    {
 3        public List<Tuple<OutputStream, string>> Streams;
 4
 5        public MemoryOutputStorage()
 6        {
 7            Streams = new List<Tuple<OutputStream, string>>();
 8        }
 9
10        public OutputStream CreateStream(OutputStreamContext context)
11        {
12            var normalizedPath = new Url(context.Uri).Pathname;
13            var uri = new Url(Path.GetFileName(normalizedPath), "memory:///").Href;
14            var outputStream = new OutputStream(new MemoryStream(), uri);
15            Streams.Add(Tuple.Create(outputStream, uri));
16            return outputStream;
17        }
18
19        public void ReleaseStream(OutputStream stream)
20        {
21            stream.Flush();
22        }
23
24        public void PrintInfo()
25        {
26            foreach (var stream in Streams)
27                Console.WriteLine($"uri:{stream.Item2}, length:{stream.Item1.Length}");
28        }
29    }

使用新的 ResourceHandler 类 – 自版本 24.3.0 起

以下代码片段显示了 MemoryResourceHandler 类中 ResourceHandler 的实现,以演示将 SVG 文档保存到内存流:

 1using System.IO;
 2using Aspose.Svg.IO;
 3using System.Collections.Generic;
 4...
 5
 6    // Prepare a path to a source SVG file
 7    string inputPath = Path.Combine(DataDir, "with-resources.svg");
 8
 9    // Initialize an SVG document
10    using (var doc = new SVGDocument(inputPath))
11    {
12        // Create an instance of the MemoryResourceHandler class and save SVG to memory
13        var resourceHandler = new MemoryResourceHandler();
14        doc.Save(resourceHandler);
15        resourceHandler.PrintInfo();
16    }

现在,不再是在IOutputStorage接口的 MemoryOutputStorage 类中实现的CreateStream()ReleaseStream()方法,而是在IOutputStorageMemoryResourceHandler类中实现了一种 HandleResource() 方法。 ResourceHandler类,您可以在其中自己创建流并在需要的地方释放它。新方法增加了查看Resource并处理有关它的更多信息的能力:

 1    internal class MemoryResourceHandler : ResourceHandler
 2    {
 3        public List<Tuple<Stream, Resource>> Streams;
 4
 5        public MemoryResourceHandler()
 6        {
 7            Streams = new List<Tuple<Stream, Resource>>();
 8        }
 9
10        public override void HandleResource(Resource resource, ResourceHandlingContext context)
11        {
12            var outputStream = new MemoryStream();
13            Streams.Add(Tuple.Create<Stream, Resource>(outputStream, resource));
14            resource
15                .WithOutputUrl(new Url(Path.GetFileName(resource.OriginalUrl.Pathname), "memory:///"))
16                .Save(outputStream, context);
17        }
18
19        public void PrintInfo()
20        {
21            foreach (var stream in Streams)
22                Console.WriteLine($"uri:{stream.Item2.OutputUrl}, length:{stream.Item1.Length}");
23        }
24    }

正如您所看到的,新方法直接使用Resource对象进行操作,无需使用OutputStream等其他类。这简化了代码并使与资源的交互更加明确和易于理解。因此,在将 SVG 文档保存到内存流时,ResourceHandler基类提供了一种更加简化和更具表现力的资源处理方式。

示例运行后,将打印有关内存存储的消息:

uri:memory:///with-resources.svg, length:556
uri:memory:///photo.png, length:57438

FileSystemResourceHandler 类与 LocalFileSystemStorage 类

LocalFileSystemStorage 类不同,新的 FileSystemResourceHandler 类不仅允许您将 SVG 文档和资源保存到选定的文件夹,而且还可以通过 ResourceHandler 基类的方法来控制将父文件中的链接写入到您正在保存的文件。

将 SVG 保存到本地文件系统存储

在这里,我们将检查使用已弃用的LocalFileSystemStorage类和新的FileSystemResourceHandler类将 SVG 文件 with-resources.svg 保存到本地文件系统存储的相同示例。

使用 LocalFileSystemStorage 类 – 24.2.0 及更早版本

源 SVG 文档与链接的图像文件位于同一目录中。 LocalFileSystemStorage(customOutDir) 构造函数创建一个文件系统存储对象。 Save(IOutputStorage) 方法获取此对象并将 SVG 保存到输出存储。

 1using System.IO;
 2using Aspose.Svg.IO;
 3...
 4
 5	// Prepare a path to a source SVG file
 6    string inputPath = Path.Combine(DataDir, "with-resources.svg");
 7
 8    // Prepare a full path to an output directory 
 9    string customOutDir = Path.Combine(Directory.GetCurrentDirectory(), "./../../../../tests-out/old/");
10
11    // Load the SVG document from a file
12    using (var doc = new SVGDocument(inputPath))
13    {
14        // Save SVG with resources
15        doc.Save(new LocalFileSystemStorage(customOutDir));
16    }

使用 FileSystemResourceHandler 类 – 自版本 24.3.0 起

FileSystemResourceHandler 类是 Aspose.SVG for .NET 中 ResourceHandler 类的实现。该类专门为将资源保存到本地文件系统而设计,为保存 SVG 文档时管理资源提供了方便且可扩展的解决方案。以下代码片段演示了FileSystemResourceHandler类的使用:

 1using System.IO;
 2using Aspose.Svg.IO;
 3...
 4
 5    // Prepare a path to a source SVG file
 6    string inputPath = Path.Combine(DataDir, "with-resources.svg");
 7
 8    // Prepare a full path to an output directory 
 9    string customOutDir = Path.Combine(Directory.GetCurrentDirectory(), "./../../../../tests-out/new/");
10
11    // Load the SVG document from a file
12    using (var doc = new SVGDocument(inputPath))
13    {
14        // Save SVG with resources
15        doc.Save(new FileSystemResourceHandler(customOutDir));
16    }

FileSystemResourceHandler(customOutDir) 构造函数采用指示资源保存位置的路径并创建 FileSystemResourceHandler 对象。 Save(resourceHandler) 方法获取该对象并将 SVG 保存到输出存储。

您可以从 GitHub 下载完整的示例和数据文件。关于从 GitHub 下载并运行示例,您可以从 如何运行示例 部分找到。

您可以尝试使用我们的 免费在线 SVG 转换器 将 SVG 文档转换为各种其他格式。

Subscribe to Aspose Product Updates

Get monthly newsletters & offers directly delivered to your mailbox.