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-архив

Здесь мы рассмотрим один и тот же пример сохранения файла 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.

Subscribe to Aspose Product Updates

Get monthly newsletters & offers directly delivered to your mailbox.