How to convert and replace EMF image to PNG with same size during PowerPoint to PDF conversion?
Syncfusion Presentation is a .NET PowerPoint Library used to create, read, edit and convert PowerPoint files to PDF and images programmatically without Microsoft Office or interop dependencies. Image Formats such as “.wmf” and “.emf” are limitation on the .NET Core and .NET target applications (using Syncfusion.PresentationRenderer.Net.Core packages). In .NET PowerPoint Library, if the Presentation file holds “.wmf” or“.emf” image, we have preserved it as RedX image with the same size of original EMF and WMF images during PowerPoint to PDF conversion to avoid pagination issue.
To preserve the expected images in the PDF, we suggest converting the metafile image formats to bitmap image formats (JPEG or PNG) and then performing PowerPoint to PDF conversion.
The conversion of metafile image formats (wmf or emf) to bitmap image formats (JPEG or PNG) externally uses the System.Drawing.Common package, which is only applicable in a Windows environment. For more information regarding this limitation, please refer to this link. Therefore, it is important to acknowledge that there is no cross-platform solution available for converting metafile image formats to PNG files.
Steps to convert and replace EMF images in PowerPoint to PNG with same size using C#:
- Create new C# .NET Core console application.
- Install the Syncfusion.PresentationRenderer.Net.Core NuGet package as a reference to your .NET Core application from NuGet.org.
Note:
-
The Syncfusion.Compression library is a dependent package of PresentationRenderer NuGet package. Once PresentationRenderer gets installed, the Compression library will automatically be installed as its dependent package.
-
Starting with v16.2.0.x, if you reference Syncfusion assemblies from trial setup or from the NuGet feed, include a license key in your projects. Refer to link to learn about generating and registering Syncfusion license key in your application to use the components without trail message.
- Include the following namespace in the Program.cs file.
C#
using Syncfusion.Presentation;
using Syncfusion.PresentationRenderer;
using Syncfusion.Pdf;
using Image = System.Drawing.Image;
using ImageFormat = System.Drawing.Imaging.ImageFormat;
- Use the following code snippet for PowerPoint to PDF conversion.
C#
//Open the file as Stream
using (FileStream fileStreamInput = new FileStream(@"Input.pptx", FileMode.Open, FileAccess.Read))
{
//Open the existing PowerPoint presentation with stream.
using (IPresentation pptxDoc = Presentation.Open(fileStreamInput))
{
//Convert the EMF images to PNG
ConvertEMFToPNG(pptxDoc);
//Initialize the PresentationRenderer to perform image conversion.
pptxDoc.PresentationRenderer = new PresentationRenderer();
using (MemoryStream pdfStream = new MemoryStream())
{
//Convert the PowerPoint document to PDF document.
using (PdfDocument pdfDocument = PresentationToPdfConverter.Convert(pptxDoc))
{
//Save the converted PDF document to MemoryStream.
pdfDocument.Save(pdfStream);
pdfStream.Position = 0;
}
//Create the output PDF file stream
using (FileStream fileStreamOutput = File.Create(@"PPTXToPDF.pdf"))
{
//Copy the converted PDF stream into created output PDF stream
pdfStream.CopyTo(fileStreamOutput);
}
}
}
}
- Use the following method to iterate through the PowerPoint file to find the EMF images.
C#
public static void ConvertEMFToPNG(IPresentation pptxDoc)
{
//Iterate in master slides.
foreach (IMasterSlide masterSlide in pptxDoc.Masters)
{
foreach (ILayoutSlide layoutSlide in masterSlide.LayoutSlides)
{
//Iterate in layout slide.
IterateShapes(layoutSlide.Shapes);
}
IterateShapes(masterSlide.Shapes);
}
//Iterate in slides.
foreach (ISlide slide in pptxDoc.Slides)
{
//Iterate in layout slide.
IterateShapes(slide.LayoutSlide.Shapes);
IterateShapes(slide.Shapes);
}
}
- Use the following method to convert and replace the EMF images to PNG image with same size.
C#
public static void IterateShapes(IShapes shapes)
{
//Iterate through each shape in the slide.
for (int i = 0; i < shapes.Count; i++)
{
IShape shape = (IShape)shapes[i];
//Identify the slide item type of the shape.
switch (shape.SlideItemType)
{
case SlideItemType.Picture:
IPicture picture = shape as IPicture;
Image image = Image.FromStream(new MemoryStream(picture.ImageData));
if (image.RawFormat.Equals(ImageFormat.Emf))
{
double height = picture.Height;
double width = picture.Width;
using (FileStream imgFile = new FileStream("Output.png", FileMode.OpenOrCreate, FileAccess.ReadWrite))
{
image.Save(imgFile, ImageFormat.Png);
image.Dispose();
}
using (FileStream imageStream = new FileStream(@"Output.png", FileMode.Open, FileAccess.ReadWrite))
{
//Creates instance for memory stream
using (MemoryStream memoryStream = new MemoryStream())
{
//Copies stream to memoryStream.
imageStream.CopyTo(memoryStream);
//Replaces the existing image with new image.
picture.ImageData = memoryStream.ToArray();
picture.Height = height;
picture.Width = width;
}
}
}
break;
case SlideItemType.GroupShape:
IGroupShape groupShape = (IGroupShape)shape;
//Iterate the shape collection in a group shape.
IterateShapes(groupShape.Shapes);
break;
case SlideItemType.AutoShape:
case SlideItemType.Placeholder:
IShape autoShape = shape as IShape;
//Check the fill type of the shape.
if (autoShape.Fill.FillType == FillType.Picture)
{
//Get the instance for picture Fill.
IPictureFill pictureFill = autoShape.Fill.PictureFill;
Image fillImage = Image.FromStream(new MemoryStream(pictureFill.ImageBytes));
if (fillImage.RawFormat.Equals(ImageFormat.Emf))
{
using (FileStream imgFile = new FileStream("Output.png", FileMode.OpenOrCreate, FileAccess.ReadWrite))
{
fillImage.Save(imgFile, ImageFormat.Png);
fillImage.Dispose();
}
using (FileStream imageStream = new FileStream(@"Output.png", FileMode.Open, FileAccess.ReadWrite))
{
//Creates instance for memory stream
using (MemoryStream memoryStream = new MemoryStream())
{
//Copies stream to memoryStream.
imageStream.CopyTo(memoryStream);
//Replaces the existing image with new image.
pictureFill.ImageBytes = memoryStream.ToArray();
}
}
}
}
break;
case SlideItemType.OleObject:
IOleObject oleObject = shape as IOleObject;
Image oleImage = Image.FromStream(new MemoryStream(oleObject.ImageData));
if (oleImage.RawFormat.Equals(ImageFormat.Emf))
{
double height = oleObject.Height;
double width = oleObject.Width;
double left = oleObject.Left;
double top = oleObject.Top;
FileStream imgFile = new FileStream("Output.png", FileMode.OpenOrCreate, FileAccess.ReadWrite);
oleImage.Save(imgFile, ImageFormat.Png);
//Gets the data of Ole object.
byte[] array = oleObject.ObjectData;
//Convert Ole object data into memory system
MemoryStream objectStream = new MemoryStream(array);
//Gets the ProgID of OLE Object
string progID = oleObject.ProgID;
//Removed the existing OLE object.
shapes.Remove(oleObject);
//Add an new OLE object to the slide with PNG format image.
IOleObject replacedOleObject = shapes.AddOleObject(imgFile, progID, objectStream);
//Set size and position of the OLE object
replacedOleObject.Left = left;
replacedOleObject.Top = top;
replacedOleObject.Width = width;
replacedOleObject.Height = height;
//Dispose all the instance.
imgFile.Dispose();
objectStream.Dispose();
oleImage.Dispose();
}
break;
}
}
}
You can download a complete working sample from GitHub.
Take a moment to peruse the documentation, where you can find basic presentation document processing options along with features like clone and merge slides and encrypt and decrypt PowerPoint presentation and most importantly PDF and image conversion with code examples.
Explore more about the rich set of Syncfusion PowerPoint Framework features.
Conclusion
I hope you enjoyed learning how to convert and replace EMF images in PPTX to PNG with same size during PowerPoint to PDF conversion using C#.
You can refer to our .NET PowerPoint Library feature tour page to know about its other groundbreaking feature representations and documentation, and how to quickly get started for configuration specifications.
For current customers, you can check out our components from the License and Downloads page. If you are new to Syncfusion, you can try our 30-day free trial to check out our other controls.
If you have any queries or require clarifications, please let us know in the comments section below. You can also contact us through our support forums, Direct-Trac, or feedback portal. We are always happy to assist you!