Aspose.Slides.NET
17.7.0
See the version list below for details.
dotnet add package Aspose.Slides.NET --version 17.7.0
NuGet\Install-Package Aspose.Slides.NET -Version 17.7.0
<PackageReference Include="Aspose.Slides.NET" Version="17.7.0" />
paket add Aspose.Slides.NET --version 17.7.0
#r "nuget: Aspose.Slides.NET, 17.7.0"
// Install Aspose.Slides.NET as a Cake Addin #addin nuget:?package=Aspose.Slides.NET&version=17.7.0 // Install Aspose.Slides.NET as a Cake Tool #tool nuget:?package=Aspose.Slides.NET&version=17.7.0
Aspose.Slides is a PowerPoint management library for working with Microsoft PowerPoint files without using Microsoft PowerPoint. It allows developers to work with PPT, PPS, POT, PPTX, PPSX, POTX and ODP files on ASP.NET web applications, web services and Windows applications.
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET Framework | net20 is compatible. net35 was computed. net35-client is compatible. net40 was computed. net40-client is compatible. net403 was computed. net45 was computed. net451 was computed. net452 was computed. net46 was computed. net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
This package has no dependencies.
NuGet packages (18)
Showing the top 5 NuGet packages that depend on Aspose.Slides.NET:
Package | Downloads |
---|---|
Aspose.Total
Aspose.Total for .NET is the most complete package of all .NET file format APIs offered by Aspose. It empowers developers to create, edit, render, print and convert between a wide range of popular document formats within any .NET, C#, ASP.NET and VB.NET applications. |
|
Verify.Aspose
Extends Verify (https://github.com/VerifyTests/Verify) to allow verification via Aspose. |
|
Weavy.Core
A class library containing core business logic, data access and utility methods required by Weavy. |
|
Aspose.Slides.WebExtensions
New Aspose.Slides HTML Export system, which allows exporting PowerPoint presentation as a highly customizable HTML/CSS/JS web document. |
|
AsposeHelpers
Aspose helpers |
GitHub repositories
This package is not used by any popular GitHub repositories.
Version | Downloads | Last updated |
---|---|---|
24.12.0 | 4,290 | 12/2/2024 |
24.11.0 | 15,961 | 11/7/2024 |
24.10.0 | 24,609 | 10/8/2024 |
24.9.0 | 26,161 | 9/12/2024 |
24.8.0 | 56,029 | 8/2/2024 |
24.7.0 | 19,289 | 7/17/2024 |
24.6.0 | 31,826 | 6/11/2024 |
24.5.0 | 40,068 | 5/8/2024 |
24.4.0 | 36,165 | 4/15/2024 |
24.3.0 | 76,385 | 3/15/2024 |
24.2.0 | 42,475 | 2/16/2024 |
24.1.0 | 60,586 | 1/19/2024 |
23.12.0 | 93,591 | 12/11/2023 |
23.11.0 | 102,855 | 11/16/2023 |
23.10.0 | 121,406 | 10/19/2023 |
23.9.0 | 88,042 | 9/20/2023 |
23.8.0 | 65,442 | 8/21/2023 |
23.7.0 | 51,090 | 7/18/2023 |
23.6.0 | 51,269 | 6/26/2023 |
23.5.0 | 146,410 | 5/19/2023 |
23.4.0 | 128,050 | 4/20/2023 |
23.3.1 | 83,766 | 3/23/2023 |
23.2.0 | 54,430 | 2/27/2023 |
23.1.0 | 196,216 | 1/27/2023 |
22.12.0 | 210,362 | 12/16/2022 |
22.11.0 | 137,836 | 11/23/2022 |
22.10.0 | 254,050 | 10/18/2022 |
22.9.0 | 116,797 | 9/13/2022 |
22.8.0 | 64,678 | 8/17/2022 |
22.7.0 | 83,292 | 7/19/2022 |
22.6.0 | 90,927 | 6/24/2022 |
22.5.0 | 99,159 | 5/17/2022 |
22.4.0 | 93,651 | 4/15/2022 |
22.3.0 | 74,177 | 3/17/2022 |
22.2.0 | 138,842 | 2/16/2022 |
22.1.0 | 119,228 | 1/19/2022 |
21.12.0 | 86,295 | 12/17/2021 |
21.11.0 | 114,148 | 11/16/2021 |
21.10.0 | 104,851 | 10/7/2021 |
21.9.0 | 377,734 | 9/20/2021 |
21.8.0 | 97,408 | 8/16/2021 |
21.7.0 | 88,601 | 7/15/2021 |
21.6.0 | 39,649 | 6/17/2021 |
21.5.0 | 70,826 | 5/18/2021 |
21.4.0 | 92,178 | 4/18/2021 |
21.3.0 | 90,108 | 3/19/2021 |
21.2.0 | 100,400 | 2/16/2021 |
21.1.0 | 96,213 | 1/21/2021 |
20.12.0 | 97,947 | 12/10/2020 |
20.11.1 | 6,568 | 12/10/2020 |
20.11.0 | 130,984 | 12/23/2020 |
20.10.0 | 82,401 | 10/19/2020 |
20.9.0 | 24,327 | 9/25/2020 |
20.8.0 | 64,373 | 8/17/2020 |
20.7.0 | 51,816 | 7/17/2020 |
20.6.0 | 67,714 | 6/12/2020 |
20.5.0 | 64,022 | 5/7/2020 |
20.4.0 | 51,214 | 4/22/2020 |
20.3.0 | 57,992 | 3/23/2020 |
20.2.0 | 88,635 | 2/17/2020 |
20.1.0 | 69,818 | 1/17/2020 |
19.12.0 | 54,937 | 12/31/2019 |
19.11.0 | 47,760 | 11/27/2019 |
19.10.0 | 72,342 | 10/29/2019 |
19.9.0 | 65,327 | 9/12/2019 |
19.8.0 | 12,797 | 8/30/2019 |
19.7.0 | 41,152 | 7/26/2019 |
19.6.0 | 29,670 | 6/25/2019 |
19.5.0 | 20,243 | 5/31/2019 |
19.4.0 | 30,818 | 4/26/2019 |
19.3.0 | 14,434 | 4/3/2019 |
19.2.0 | 37,469 | 2/28/2019 |
19.1.0 | 86,055 | 1/30/2019 |
18.12.0 | 53,524 | 12/27/2018 |
18.11.0 | 30,065 | 11/30/2018 |
18.10.0 | 54,301 | 10/30/2018 |
18.9.0 | 18,321 | 9/30/2018 |
18.8.0 | 17,742 | 8/29/2018 |
18.7.0 | 30,882 | 7/27/2018 |
18.6.0 | 37,595 | 7/1/2018 |
18.5.0 | 17,359 | 5/30/2018 |
18.4.0 | 35,289 | 5/3/2018 |
18.3.0 | 19,083 | 4/1/2018 |
18.2.1 | 55,700 | 3/7/2018 |
18.2.0 | 31,976 | 2/28/2018 |
18.1.0 | 30,357 | 1/30/2018 |
17.12.1 | 15,587 | 12/26/2017 |
17.12.0 | 4,771 | 12/16/2017 |
17.11.0 | 7,786 | 11/30/2017 |
17.10.0 | 27,222 | 10/31/2017 |
17.9.1 | 7,443 | 10/12/2017 |
17.9.0 | 6,999 | 10/2/2017 |
17.8.0 | 56,008 | 8/30/2017 |
17.7.0 | 19,986 | 7/31/2017 |
17.6.0 | 11,709 | 7/1/2017 |
17.5.0 | 8,598 | 5/31/2017 |
17.4.0 | 9,979 | 4/28/2017 |
17.3.0 | 17,335 | 4/2/2017 |
17.2.0 | 37,895 | 3/1/2017 |
17.1.0 | 8,690 | 1/31/2017 |
16.12.1 | 15,275 | 1/16/2017 |
16.12.0 | 5,771 | 12/27/2016 |
16.11.0 | 9,437 | 11/30/2016 |
16.10.0 | 11,816 | 11/4/2016 |
16.9.0 | 8,648 | 10/12/2016 |
16.8.0 | 42,225 | 9/27/2016 |
16.7.0 | 5,320 | 8/22/2016 |
16.6.0 | 55,247 | 7/15/2016 |
16.5.0 | 13,239 | 6/16/2016 |
16.4.0 | 9,490 | 5/16/2016 |
16.3.0 | 18,492 | 4/11/2016 |
16.2.0 | 9,710 | 3/17/2016 |
16.1.0 | 22,889 | 2/4/2016 |
15.11.0 | 31,683 | 1/11/2016 |
15.10.0 | 13,776 | 12/10/2015 |
15.9.0 | 10,570 | 11/6/2015 |
15.8.1 | 4,323 | 10/16/2015 |
15.8.0 | 5,171 | 10/5/2015 |
15.7.0 | 76,700 | 9/3/2015 |
15.6.0 | 36,065 | 7/22/2015 |
15.5.0 | 11,409 | 6/16/2015 |
15.4.0 | 8,551 | 5/14/2015 |
15.3.1 | 6,620 | 4/23/2015 |
15.3.0 | 4,025 | 4/14/2015 |
15.2.0 | 42,503 | 3/6/2015 |
15.1.0 | 12,272 | 2/3/2015 |
14.10.0 | 17,482 | 11/28/2014 |
14.9.0 | 7,724 | 11/11/2014 |
14.8.1 | 4,701 | 10/24/2014 |
14.8.0 | 3,880 | 10/16/2014 |
14.7.0 | 5,086 | 9/7/2014 |
14.6.0 | 4,682 | 8/6/2014 |
14.5.0 | 8,835 | 7/16/2014 |
14.4.0 | 5,974 | 6/2/2014 |
14.3.0 | 8,410 | 5/6/2014 |
14.2.0 | 4,407 | 3/24/2014 |
14.1.2 | 6,636 | 2/17/2014 |
14.1.1 | 3,717 | 2/10/2014 |
14.1.0.2 | 3,595 | 2/6/2014 |
13.12.0 | 4,596 | 12/30/2013 |
8.4.2 | 47,484 | 6/5/2014 |
8.4.1 | 4,243 | 5/6/2014 |
8.4.0 | 6,914 | 3/3/2014 |
8.3.0.1 | 4,062 | 2/3/2014 |
8.2.0 | 3,831 | 12/27/2013 |
8.1.0 | 11,428 | 12/16/2013 |
8.0.0 | 5,012 | 10/25/2013 |
7.9.0 | 4,249 | 10/8/2013 |
7.8.0 | 3,864 | 9/3/2013 |
7.7.0 | 11,909 | 8/4/2013 |
7.6.0 | 7,218 | 7/5/2013 |
7.5.0 | 6,256 | 5/27/2013 |
7.4.0 | 10,292 | 4/24/2013 |
7.3.0 | 3,640 | 4/10/2013 |
7.2.0 | 4,295 | 3/8/2013 |
7.1.0 | 6,007 | 1/28/2013 |
7.0.0 | 6,134 | 12/31/2012 |
6.9.0 | 3,613 | 12/10/2012 |
6.8.0 | 3,988 | 10/30/2012 |
6.7.0 | 4,314 | 10/4/2012 |
6.6.0 | 3,520 | 9/13/2012 |
6.5.0 | 3,865 | 7/27/2012 |
6.4.0 | 3,612 | 6/27/2012 |
6.3.0 | 3,542 | 5/29/2012 |
6.2.0 | 3,736 | 5/7/2012 |
6.1.0 | 3,647 | 3/28/2012 |
6.0.0 | 4,005 | 3/2/2012 |
5.9.0.1 | 8,007 | 2/16/2012 |
5.9.0 | 7,287 | 2/16/2012 |
SLIDESNET-38556 - IOleObjectFrame.ObjectData returns byte stream of the entire ole objects
SLIDESNET-39011 - PPTX to PDF failed in Aspose.Slides for .NET 15.2
SLIDESNET-39100 - Support for explicitly setting PNG image format when adding image into presentation
SLIDESNET-34027 - Support for adding columns in text box
SLIDESNET-38595 - Optimize the memory consumption caused by BLOB objects
SLIDESNET-37660 - SVG Import
SLIDESNET-38554 - Get text added to the shapes associated with the SmartArt nodes
SLIDESNET-38558 - Get the shape Id property set by Microsoft using Aspose library
SLIDESNET-39110 - Support for inserting SVG in slide
SLIDESNET-38015 - When PPTX is converted to PDF, the values in chart are missing
SLIDESNET-39052 - When PPTX is converted to PDF, font size in output is increased.
SLIDESNET-38905 - Exception while setting Frame settings for shape of SmartArtNode
SLIDESNET-39050 - Image replacement doesn't work if jpeg picture is passed
SLIDESNET-35162 - Text improperly rendered in generated PDF
SLIDESNET-35812 - Chart Labels are not coming fine after conversion from PPTX to PDF
SLIDESNET-38357 - Pptx not converted properly to pdf
SLIDESNET-38427 - Out of Memory Exception thrown on loading huge presentations and Improving memory consumption
SLIDESNET-34377 - Arrow lines are missing or improperly rendered in generated PDF
SLIDESNET-34740 - Text failed to render in PDF for PPT when using PresentationEx class
SLIDESNET-34741 - Text failed to render in PDF for PPT
SLIDESNET-34797 - Text is improperly rendered in generated thumbnail
SLIDESNET-35621 - Shapes move when existing file is opened and saved
SLIDESNET-35736 - Improper chart rendering in Pdf and thumbnails
SLIDESNET-37579 - Shadow effect on a text disappears after saving a ppt
SLIDESNET-38258 - Font substitution does not work when converting pptx to png
SLIDESNET-38259 - Exception on converting pptx to pdf
SLIDESNET-38508 - Font becomes bold after converting ppt to pdf
SLIDESNET-38525 - Pptx not converted properly to pdf
SLIDESNET-38561 - Unexpected text shadow effect shows up
SLIDESNET-38607 - Text missing in generated result svg format
SLIDESNET-38908 - PptxRead exception on loading presentaiton
SLIDESNET-38916 - Text on chart is missing in generated thumbnail
SLIDESNET-38941 - Performance of ISmartArtNode.TextFrame is decreased for each next Node
SLIDESNET-38957 - Pptx not converted properly to pdf and thumbnails
SLIDESNET-38960 - Exception on loading presentation
SLIDESNET-38991 - Exception when converting Pptx to Pdf
SLIDESNET-39002 - Image color missing in generated thumbnail
SLIDESNET-39014 - Wrong coordinates are returned for paragraph position
SLIDESNET-39030 - Setting label value for workbook cell not working for data point
SLIDESNET-39044 - Comments are missing in exported PDF
SLIDESNET-39056 - Invalid file generated when converting PPT file to PPTX
SLIDESNET-39058 - Images not properly generated from presentation file
Public API Changes
AddFromSvg methods were added to IImageCollection interface and ImageCollection class
/// <summary>
/// Add an image to a presentation from Svg.
/// </summary>
/// <remarks>Svg to Metafile(EmfPlusOnly) conversion will be performed</remarks>
/// <param name="svgContent">Svg content.</param>
/// <returns>Added image.</returns>
IPPImage AddFromSvg(string svgContent);
/// <summary>
/// Add an image to a presentation from Svg.
/// </summary>
/// <remarks>Svg to Metafile(EmfPlusOnly) conversion will be performed</remarks>
/// <param name="svgContent">Svg content.</param>
/// <param name="externalResResolver">A callback object used to fetch external objects. If this parameter is null all external objects will be ignored.</param>
/// <param name="baseUri">Base URI of the specified Svg. Used to resolve relative links.</param>
/// <returns>Added image.</returns>
IPPImage AddFromSvg(string svgContent, IExternalResourceResolver externalResResolver, string baseUri);
These methods provide ability to insert Svg fragment to the presentation's image collection.
Sample 1
using (var p = new Presentation())
{
var svgContent = File.ReadAllText(svgPath);
var emfImage = p.Images.AddFromSvg(svgContent);
p.Slides[0].Shapes.AddPictureFrame(ShapeType.Rectangle, 0, 0, emfImage.Width, emfImage.Height, emfImage);
p.Save(outPptxPath, SaveFormat.Pptx);
}
Sample 2 (with default external resources resolver)
using (var p = new Presentation())
{
var svgContent = File.ReadAllText(new Uri(new Uri(baseDir), "image1.svg").AbsolutePath);
var emfImage = p.Images.AddFromSvg(svgContent, new ExternalResourceResolver(), baseDir);
p.Slides[0].Shapes.AddPictureFrame(ShapeType.Rectangle, 0, 0, emfImage.Width, emfImage.Height, emfImage);
p.Save(outPptxPath, SaveFormat.Pptx);
}
Please note: Using this default external resource resolver could create a vulnerability when client provided HTML or SVG file will make server software to obtain local or network file. Use with caution. It is recommended not to specify ExternalResourceResolver at all (only embedded objects will be read - see "Sample 1") or create some subclass which checks if specified uri is valid.
ColumnCount and ColumnSpacing properties have been added to ITextFrameFormat interface and to TextFrameFormat class
Property ColumnCount and ColumnSpacing has been added to ITextFrameFormat interface and TextFrameFormat class respectively.
These properties specify the number of columns in textbox and set an amount of spacing in points between columns.
Code example:
using (Presentation presentation = new Presentation())
{
// Get the first slide of presentation
ISlide slide = presentation.Slides[0];
// Add an AutoShape of Rectangle type
IAutoShape aShape = slide.Shapes.AddAutoShape(ShapeType.Rectangle, 100, 100, 300, 300);
// Add TextFrame to the Rectangle
aShape.AddTextFrame("All these columns are limited to be within a single text container -- " +
"you can add or delete text and the new or remaining text automatically adjusts " +
"itself to flow within the container. You cannot have text flow from one container " +
"to other though -- we told you PowerPoint's column options for text are limited!");
// Get text format of TextFrame
ITextFrameFormat format = aShape.TextFrame.TextFrameFormat;
// Specify number of columns in TextFrame
format.ColumnCount = 3;
// Specify spacing between columns
format.ColumnSpacing = 10;
// Save created presentation
presentation.Save("ColumnCount.pptx", SaveFormat.Pptx);
}
IHtmlExternalResolver interface and HtmlExternalResolver class become obsolete
Use IExternalResourceResolver/ExternalResourceResolver instead. Will be removed in 17.12 release.
New API related to the BLOBs management has been added
New BLOBs API
Overview
A Binary Large Object (BLOB) is a binary data stored as a single entity, that must be handled in a special way because of its size. It cannot be considered that any BLOB object may fit in the process's memory - or, even if it can, it may lead to an issues like undesirable high memory consumption or increase the chances of "out of memory" exceptions, and other inappropriate effects.
Presentaion can be considered as BLOB itself or can contain BLOBs - such as large video or audio files. To prevent unwanted memory consumption and other issues a new BLOBs management functionality was introduced.
The way to avoid BLOBs loading into memory is to use streams - the instances of classes inherited from the base Stream class. A new functions were added to the public API to support passing streams as arguments - to treat these streams as BLOBs and guarantee that no process's memory will be wasted to store them.
What is important about streams is who owns them. As an example, you may open the FileStream and pass this stream to Presentation's instance. You may want to delete this file later, while the Presentation's instance is still here - but if it is deleted, how will this instance use it to save the presentation in the other format, for example?
To solve this possible conflict an idea of "possession" of the stream was introduced. When you pass a stream to Presentation, you may choose the behavior the most suitable for you - either let Presentation lock the stream and use it later or read the whole stream and then release it. Under the hood a different techniques might be used to handle large streams - including copying the whole stream in a temporary file and cleanup later when Presentation's instance will be disposed. Obviously, passing the stream to Presentation and let it be locked is more effective and not introduce an overhead related to the file system operations, but it may be inappropriate if you can't let this stream be locked and want close it before Presentation's instance will be disposed. So here the choice is up to the Presentation's instance owner.
Presentation source locking behavior
The source of the presentation is the data from which this presentation will be loaded and an instance of the Presentation class will be created. It can be a file or an instance of the Stream. There're two options that can be selected for the Presentation construction - they represented by PresentationLockingBehavior enumeration members.
LoadAndRelease - the source will be released immediately after Presentation's object will be constructed. If usage of the temporary files is disabled (IBlobManagementOptions.IsTemporaryFilesAllowed is set to false), the whole presentation will be loaded into memory.
KeepLocked - the source (file or Stream) will be locked. One of the major property of streams is that they might be seekable or not. In some cases like parsing the whole presentation, we must have the whole stream to build the DOM. So in this case the source might not be seekable (e.g. in case of NetworkStream), and it's needed to load the whole stream in temporary storage to parse the presentation. Usage of the temporary files must be enabled in this mode (IBlobManagementOptions.IsTemporaryFilesAllowed is set to true), an exception will be thrown otherwise.
Customizations of BLOBs management behavior
A number of options can be customized to provide the behavior most suitable for a specific environment and achieve the optimal ratio of performance and memory consumption in any particular case.
In a number of cases BLOB management uses a temporary files to handle situations when the source stream can't be locked by Presentation object. You may disable the usage of temporary files using IBlobManagementOptions.IsTemporaryFilesAllowed property. In this case any stream that can't be locked will be downloaded in memory.
Beside that, the root path of the temporary files can be changed. By default, the system's default temporary files folder is used.
The other option that can be customized is the amount of process's memory that can be safely used to store the BLOBs before it will be dumped to a temporary files. It's faster to avoid the file system operations if there is no memory pressure, and the IBlobManagementOptions.MaxBlobsBytesInMemory property can be used to set the value the most appropriate for every particular case. The default value is 600Mb.
Working with BLOBs
Open and save the large presentation
Here's is the sample of opening and saving the very large presentation:
static void OpenAndSaveLargePresentation()
{
// supposed the size of presentation is very large, let's say more than 2Gb
const string pathToVeryLargePresentationFile = "veryLargePresentation.pptx";
LoadOptions loadOptions = new LoadOptions
{
BlobManagementOptions = {
// let's choose the KeepLocked behavior - the "veryLargePresentation.pptx" will be locked for
// the Presentation's instance lifetime, but we don't need to load it into memory or copy into
// thetemporary file
PresentationLockingBehavior = PresentationLockingBehavior.KeepLocked,
}
};
using (Presentation pres = new Presentation(pathToVeryLargePresentationFile, loadOptions))
{
// the huge presentation is loaded and ready to use, but the memory consumption is still low.
// make any changes to the presentation.
pres.Slides[0].Name = "Very large presentation";
// presentation will be saved to the other file, the memory consumptions still low during saving.
pres.Save("veryLargePresentation-copy.pptx", SaveFormat.Pptx);
// can't do that! IO exception will be thrown, because the file is locked while pres objects will
// not be disposed
File.Delete(pathToVeryLargePresentationFile);
}
// it's ok to do it here, the source file is not locked by pres object
File.Delete(pathToVeryLargePresentationFile);
}
Adding new BLOB to the presentation
This example demonstrates how to include the large BLOB (video file in that case) and prevent a high memory consumption.
static void AddingNewBlobToPresentation()
{
// supposed we have the very large video file we want to include into the presentation
const string pathToVeryLargeVideo = "veryLargeVideo.avi";
// create a new presentation which will contain this video
using (Presentation pres = new Presentation())
{
using (FileStream fileStream = new FileStream(pathToVeryLargeVideo, FileMode.Open))
{
// let's add the video to the presentation - we choose KeepLocked behavior, because we not
// have an intent to access the "veryLargeVideo.avi" file.
IVideo video = pres.Videos.AddVideo(fileStream, LoadingStreamBehavior.KeepLocked);
pres.Slides[0].Shapes.AddVideoFrame(0, 0, 480, 270, video);
// save the presentation. Despite that the output presentation will be very large, the memory
// consumption will be low the whole lifetime of the pres object
pres.Save("presentationWithLargeVideo.pptx", SaveFormat.Pptx);
}
}
}
Exporting BLOB from presentation into stream
Consider that we have a very large presentation containing multiple large BLOBs - audio and video files. We want to extract these files from presentation and don't want to load this presentation into memory to keep our memory consumption low. Here's is an example how we can achieve that:
static void ExportBlobsFromPresentaion()
{
// supposed the presentation contains a multiple audios and videos and it size is huge.
const string hugePresentationWithAudiosAndVideosFile = @"c:\bin\aspose\Tasks\020, 38595\orig\Large Video File Test1.pptx";
LoadOptions loadOptions = new LoadOptions
{
BlobManagementOptions =
{
// lock the source file and don't load it into memory
PresentationLockingBehavior = PresentationLockingBehavior.KeepLocked,
}
};
// create the Presentation's instance, lock the "hugePresentationWithAudiosAndVideos.pptx" file.
using (Presentation pres = new Presentation(hugePresentationWithAudiosAndVideosFile, loadOptions))
{
// let's save each video to a file. to prevent memory usage we need a buffer which will be used
// to exchange tha data from the presentation's video stream to a stream for newly created video file.
byte[] buffer = new byte[8 * 1024];
// iterate through the videos
for (var index = 0; index < pres.Videos.Count; index++)
{
IVideo video = pres.Videos[index];
// open the presentation video stream. Please note that we intentionally avoid accessing properties
// like video.BinaryData - this property returns a byte array containing full video, and that means
// this bytes will be loaded into memory. We will use video.GetStream, which will return Stream and
// that allows us to not load the whole video into memory.
using (Stream presVideoStream = video.GetStream())
{
using (FileStream outputFileStream = File.OpenWrite($"video{index}.avi"))
{
int bytesRead;
while ((bytesRead = presVideoStream.Read(buffer, 0, buffer.Length)) > 0)
{
outputFileStream.Write(buffer, 0, bytesRead);
}
}
}
// memory consumption will stay low no matter what size the videos or presentation is.
}
// do the same for audios if needed.
}
}
API
A number of the new properties, classes and enums has been added to support BLOBs handling.
ILoadOptions
BlobManagementOptions property of type IBlobManagementOptions has been added. It represents the options which can be used to manage Binary Large Objects (BLOBs) handling behavior, such as using of temporary files or max BLOBs bytes in memory.
IBlobManagementOptions interface
A new interface IBlobManagementOptions has been added. It inteded to configure a a different behavior aspects regarding BLOBs handling for the IPresentation instance lifetime.
PresentationLockingBehavior property of PresentationLockingBehavior enum. This property defines if an instance of the Presentation class can be an owner of the source - file or stream during the instance lifetime. If the instance is an owner, it locks the source.
IsTemporaryFilesAllowed of type bool. This property defines if temporary files can be created while working with BLOBs, what greatly decreases the memory consumption but requires permissions to create files.
TempFilesRootPath of type string. The root path where temporary files will be created. Hosting process should have permissions to create files and folders there.
MaxBlobsBytesInMemory of type ulong. Defines the maximum amount (in bytes) that all BLOBs in total may occupy in memory.
PresentationLockingBehavior enum
The new PresentationLockingBehavior enum has been added, it values represents the behavior regarding treating the IPresentation source (file or Stream) while loading and working with an instance of IPresentation. It has the following members:
LoadAndRelease - The source will be locked only for a time of IPresentation constructor execution.
KeepLocked - The source will be locked for a whole lifetime of IPresentation instance, until it will be disposed.
IVideoCollection and IAudioCollection
A new method has been added to IVideoCollection and IAudioCollection to support adding large videos and audios as streams to treat them as BLOBs:
IVideo AddVideo(Stream stream, LoadingStreamBehavior loadingStreamBehavior)
IAudio AddAudio(Stream stream, LoadingStreamBehavior loadingStreamBehavior)
LoadingStreamBehavior
This new enum is used to select proper behavior to handle the stream. It contains the following possible values:
ReadStreamAndRelease - the stream will be read to the end and then released - i.e. it will be guaranteed that this stream will not be used by IPresentation instance in the future.
KeepLocked - the stream will be locked inside the IPresentation object, i.e. the ownership of the stream will be transferred. The IPresentation object will be responsible to correctly dispose the stream when this object will be disposed itself.
IVideo and IAudio
To support getting large BLOBs inside presentation as Stream a new method has been added:
Stream GetStream()
It returns Stream stream for reading. Please note that you must use 'using' or close stream after using.
New IExternalResourceResolver interface and ExternalResourceResolver class were added
New IExternalResourceResolver interface was added as a replacement of existing IHtmlExternalResolver (become obsolete).
This is a callback interface used to resolve external resources during Html, Svg documents import.
/// <summary>
/// Callback interface used to resolve external resources during Html, Svg documents import.
/// </summary>
[ComVisible(true), Guid("88ff6edd-d6d4-43e4-b25a-7806671fe7ca")]
public interface IExternalResourceResolver
{
/// <summary>
/// Resolves the absolute URI from the base and relative URIs.
/// </summary>
/// <param name="baseUri">Base URI of linking objects</param>
/// <param name="relativeUri">Relative URI to the linked object.</param>
/// <returns>Absolute URI or null if the relative URI cannot be resolved.</returns>
string ResolveUri(string baseUri, string relativeUri);
/// <summary>
/// Maps a URI to an object containing the actual resource.
/// </summary>
/// <param name="absoluteUri">Absolute URI to the object.</param>
/// <returns> A <see cref="System.IO.Stream"/> object or null if resource cannot be streamed.</returns>
System.IO.Stream GetEntity(string absoluteUri);
}
ExternalResourceResolver is default implementation of IExternalResourceResolver.
Please note: Using ExternalResourceResolver could create a vulnerability when client provided HTML or SVG file will make server software to obtain local or network file. Use with caution. It is recommended not to specify ExternalResourceResolver at all (only embedded objects will be read - see "Sample 1") or create some subclass which checks if specified uri is valid.
New property EmbeddedFileData has been added to IOleObjectFrame
A new property EmbeddedFileData has been added to IOleObjectFrame. It's needed to retrieve the file data of embedded OLE object.
For example, when an image has been embedded into presentation, its data can be accessed through EmbeddedFileData property:
using (Presentation pres = new Presentation(pptxFileName))
{
IOleObjectFrame oleObjectFrame = (IOleObjectFrame)pres.Slides[0].Shapes[0];
string fileName = oleObjectFrame.EmbeddedFileName;
byte[] data = oleObjectFrame.EmbeddedFileData;
}
OfficeInteropShapeId property was added to IShape interface and Shape class respectively
Property OfficeInteropShapeId was added to IShape interfaces and Shape class respectively.
This property allows getting unique shape identifier in slide scope in contrast to the UniqueId property, which allows obtaining a unique identifier in presentation scope.
The value returned by OfficeInteropShapeId property corresponds to the value of the Id of the Microsoft.Office.Interop.PowerPoint.Shape object.
Code example:
using (Presentation presentation = new Presentation("Presentation.pptx"))
{
// Getting unique shape identifier in slide scope
long officeInteropShapeId = presentation.Slides[0].Shapes[0].OfficeInteropShapeId;
}
TextFrame property has been added to ISmartArtShape interface and SmartArtShape class
TextFrame property has been added to ISmartArtShape interface and SmartArtShape class respectively.
This property allows you to get all text from SmartArt if it has not only nodes text.
using (Presentation pres = new Presentation("Presentation.pptx"))
{
ISlide slide = presentation.Slides[0];
ISmartArt smartArt = (ISmartArt)slide.Shapes[0];
ISmartArtNodeCollection smartArtNodes = smartArt.AllNodes;
foreach (ISmartArtNode smartArtNode in smartArtNodes)
{
foreach (ISmartArtShape nodeShape in smartArtNode.Shapes)
{
if (nodeShape.TextFrame != null)
Console.WriteLine(nodeShape.TextFrame.Text);
}
}
}