Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions Images/Extract-EMF-Images-In-PPTX/.NET/Extract-EMF-Images.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.11.35327.3
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Extract-EMF-Images", "Extract-EMF-Images\Extract-EMF-Images.csproj", "{82E919F2-6EA6-4E54-BF73-9D3133B56F4A}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{82E919F2-6EA6-4E54-BF73-9D3133B56F4A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{82E919F2-6EA6-4E54-BF73-9D3133B56F4A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{82E919F2-6EA6-4E54-BF73-9D3133B56F4A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{82E919F2-6EA6-4E54-BF73-9D3133B56F4A}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {446047E7-FDD0-4F0E-A910-B67785529857}
EndGlobalSection
EndGlobal
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<RootNamespace>Extract_EMF_Images</RootNamespace>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Syncfusion.PresentationRenderer.Net.Core" Version="*" />
</ItemGroup>
<ItemGroup>
<None Update="Data\Input.pptx">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Output\.gitkeep">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

105 changes: 105 additions & 0 deletions Images/Extract-EMF-Images-In-PPTX/.NET/Extract-EMF-Images/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
using Syncfusion.Drawing;
using Syncfusion.Presentation;

public static class Program
{
public static int imageIndex = 0;
public static string outputPath = @"Output";

public static void Main()
{
// Open the PowerPoint file as a stream.
using (FileStream inputStream = new FileStream(Path.GetFullPath(@"Data/Input.pptx"), FileMode.Open, FileAccess.Read))
{
// Load the presentation from the stream.
using (IPresentation presentation = Presentation.Open(inputStream))
{
// Extract EMF images from Masters and their Layout slides
foreach (IMasterSlide master in presentation.Masters)
{
// Process shapes placed on the master slide
foreach (IShape shape in master.Shapes)
{
ProcessShape(shape);
}
// Process shapes placed on each layout slide under this master
foreach (ILayoutSlide layoutSlide in master.LayoutSlides)
{
foreach (IShape shape in layoutSlide.Shapes)
{
ProcessShape(shape);
}
}
}
// Extract EMF images from Normal slides
foreach (ISlide slide in presentation.Slides)
{
foreach (IShape shape in slide.Shapes)
{
ProcessShape(shape);
}
}
}
}
}

/// <summary>
/// Processes a shape: saves EMF images and recurses through group shapes.
/// </summary>
private static void ProcessShape(IShape shape)
{
// If the shape is a picture with EMF format
if (shape is IPicture picture && picture.ImageFormat == ImageFormat.Emf)
{
SaveEMFImage(picture);
}
// Shape is not a picture object, but its FILL contains a picture(Picture Fill)
if (shape.Fill != null && shape.Fill.FillType == FillType.Picture)
{
// Validate bytes exist and check if those bytes represent an EMF file
var bytes = shape.Fill.PictureFill.ImageBytes;
if (bytes != null && bytes.Length > 0 && IsEmf(bytes))
{
string filePath = Path.Combine(outputPath, $"Slide_Image_{++imageIndex}.emf");
File.WriteAllBytes(filePath, bytes);
}
}

// If the shape is a group, process child shapes
if (shape is IGroupShape group)
{
foreach (IShape child in group.Shapes)
{
ProcessShape(child);
}
}
}

/// <summary>
/// Saves EMF image from the picture shape.
/// </summary>
private static void SaveEMFImage(IPicture picture)
{
byte[] imageData = picture.ImageData;

if (imageData != null && imageData.Length > 0)
{
string extension = picture.ImageFormat.ToString().ToLower();
string filePath = Path.Combine(outputPath, $"Slide_Image_{++imageIndex}.{extension}");
File.WriteAllBytes(filePath, imageData);
}
}

/// <summary>
/// Checks whether the given byte[] looks like an EMF file.
/// </summary>
private static bool IsEmf(byte[] bytes)
{
if (bytes == null || bytes.Length < 44) return false;

// EMF signature " EMF" = 0x20 0x45 0x4D 0x46 (little endian uint32 => 0x464D4520)
// At offset 40..43
uint signature = BitConverter.ToUInt32(bytes, 40);
return signature == 0x464D4520;
}
}