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 эти устаревшие классы будут удалены.
Deprecated | New |
---|---|
IOutputStorage Interface | ResourceHandler Class |
LocalFileSystemStorage Class | FileSystemResourceHandler Class |
Документ SVG может содержать различные ресурсы, такие как CSS, внешние изображения и файлы. В этой статье мы рассмотрим случаи сохранения SVG-документов с ресурсами в Zip-архив, поток памяти и хранилище локальной файловой системы. Aspose.SVG for .NET продолжает разрабатывать и совершенствовать способы сохранения SVG со всеми связанными файлами. Здесь мы рассмотрим примеры сохранения файлов с использованием устаревших классов и предложим продвинутые решения по реализации новых классов.
Класс ResourceHandler заменяет IOutputStorage интерфейс
Класс
ResourceHandler позволяет разработчикам реализовать метод HandleResource()
, в котором вы можете самостоятельно создать поток и выпустить его там, где вам это нужно. Новый метод добавляет возможность видеть Resource
и обрабатывать дополнительную информацию о нем. Таким образом, приняв класс ResourceHandler
, разработчики смогут получить выгоду от более оптимизированного и выразительного подхода к управлению ресурсами, что приведет к созданию более чистого, удобного в обслуживании и гибкого кода при сохранении документов SVG.
Сохранить SVG в ZIP-архив
Здесь мы рассмотрим один и тот же пример сохранения файла
with-resources.svg в Zip-архив с использованием устаревшего интерфейса IOutputStorage
и нового класса ResourceHandler
.
Использование IOutputStorage – 24.2.0 и более ранние версии
Интерфейс IOutputStorage
был базовым интерфейсом, который поддерживал создание потоков вывода и управление ими. Вы можете реализовать интерфейс IOutputStorage
, создав класс ZipStorage для сохранения 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 }
В следующем фрагменте кода показана реализация IOutputStorage
в классе ZipStorage для демонстрации сохранения документа 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# показано, как сохранить документ SVG с ресурсами в Zip-архив с помощью класса ZipResourceHandler:
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 }
В следующем фрагменте кода показана реализация ResourceHandler
в классе ZipResourceHandler для демонстрации сохранения документа SVG с ресурсами в Zip-архив. Метод
HandleResource() класса ZipResourceHandler
отвечает за обработку каждого ресурса в процессе сохранения при создании 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 в потоки памяти
Давайте рассмотрим пример C# сохранения файла SVG со связанными ресурсами в поток памяти с использованием устаревшего интерфейса IOutputStorage
и нового класса
ResourceHandler. Исходный документ
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
В следующем фрагменте кода показана реализация IOutputStorage
в классе MemoryOutputStorage для демонстрации сохранения документа 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
В следующем фрагменте кода показана реализация ResourceHandler
в классе MemoryResourceHandler для демонстрации сохранения документа 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 }
Вместо методов CreateStream()
и ReleaseStream()
, реализованных в классе MemoryOutputStorage
интерфейса IOutputStorage
, теперь существует один метод
HandleResource(), реализованный в классе MemoryResourceHandler
класса 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
. Это упрощает код и делает взаимодействие с ресурсами более явным и понятным. Таким образом, базовый класс ResourceHandler
предлагает более упрощенный и выразительный способ обработки ресурсов при сохранении документов SVG в потоки памяти.
После запуска примера будет напечатано сообщение о хранении в памяти:
uri:memory:///with-resources.svg, length:556
uri:memory:///photo.png, length:57438
Класс FileSystemResourceHandler заменяет класс LocalFileSystemStorage
В отличие от класса LocalFileSystemStorage
, новый класс
FileSystemResourceHandler позволяет не только сохранять SVG-документы и ресурсы в выбранную папку, но и используя методы базового класса
ResourceHandler контролировать запись ссылки в родительских файлах на сохраняемые вами файлы.
Сохранить SVG в хранилище локальной файловой системы
Здесь мы рассмотрим тот же пример сохранения файла SVG
with-resources.svg в хранилище локальной файловой системы с использованием устаревшего класса LocalFileSystemStorage
и нового класса FileSystemResourceHandler
.
Использование класса 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
является реализацией класса ResourceHandler
в Aspose.SVG for .NET. Этот класс, специально разработанный для сохранения ресурсов в локальной файловой системе, предоставляет удобное и расширяемое решение для управления ресурсами при сохранении документов 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.