diff --git a/Images/Extract-EMF-Images-In-PPTX/.NET/Extract-EMF-Images.sln b/Images/Extract-EMF-Images-In-PPTX/.NET/Extract-EMF-Images.sln new file mode 100644 index 0000000..bcce48d --- /dev/null +++ b/Images/Extract-EMF-Images-In-PPTX/.NET/Extract-EMF-Images.sln @@ -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 diff --git a/Images/Extract-EMF-Images-In-PPTX/.NET/Extract-EMF-Images/Data/Input.pptx b/Images/Extract-EMF-Images-In-PPTX/.NET/Extract-EMF-Images/Data/Input.pptx new file mode 100644 index 0000000..c2eb6ad Binary files /dev/null and b/Images/Extract-EMF-Images-In-PPTX/.NET/Extract-EMF-Images/Data/Input.pptx differ diff --git a/Images/Extract-EMF-Images-In-PPTX/.NET/Extract-EMF-Images/Extract-EMF-Images.csproj b/Images/Extract-EMF-Images-In-PPTX/.NET/Extract-EMF-Images/Extract-EMF-Images.csproj new file mode 100644 index 0000000..59cc701 --- /dev/null +++ b/Images/Extract-EMF-Images-In-PPTX/.NET/Extract-EMF-Images/Extract-EMF-Images.csproj @@ -0,0 +1,22 @@ + + + + Exe + net8.0 + Extract_EMF_Images + enable + enable + + + + + + + + Always + + + Always + + + diff --git a/Images/Extract-EMF-Images-In-PPTX/.NET/Extract-EMF-Images/Output/Slide_Image_1.emf b/Images/Extract-EMF-Images-In-PPTX/.NET/Extract-EMF-Images/Output/Slide_Image_1.emf new file mode 100644 index 0000000..925cb7e Binary files /dev/null and b/Images/Extract-EMF-Images-In-PPTX/.NET/Extract-EMF-Images/Output/Slide_Image_1.emf differ diff --git a/Images/Extract-EMF-Images-In-PPTX/.NET/Extract-EMF-Images/Output/Slide_Image_2.emf b/Images/Extract-EMF-Images-In-PPTX/.NET/Extract-EMF-Images/Output/Slide_Image_2.emf new file mode 100644 index 0000000..ab869f5 Binary files /dev/null and b/Images/Extract-EMF-Images-In-PPTX/.NET/Extract-EMF-Images/Output/Slide_Image_2.emf differ diff --git a/Images/Extract-EMF-Images-In-PPTX/.NET/Extract-EMF-Images/Output/Slide_Image_3.emf b/Images/Extract-EMF-Images-In-PPTX/.NET/Extract-EMF-Images/Output/Slide_Image_3.emf new file mode 100644 index 0000000..a27590b Binary files /dev/null and b/Images/Extract-EMF-Images-In-PPTX/.NET/Extract-EMF-Images/Output/Slide_Image_3.emf differ diff --git a/Images/Extract-EMF-Images-In-PPTX/.NET/Extract-EMF-Images/Output/Slide_Image_4.emf b/Images/Extract-EMF-Images-In-PPTX/.NET/Extract-EMF-Images/Output/Slide_Image_4.emf new file mode 100644 index 0000000..9135a87 Binary files /dev/null and b/Images/Extract-EMF-Images-In-PPTX/.NET/Extract-EMF-Images/Output/Slide_Image_4.emf differ diff --git a/Images/Extract-EMF-Images-In-PPTX/.NET/Extract-EMF-Images/Output/Slide_Image_5.emf b/Images/Extract-EMF-Images-In-PPTX/.NET/Extract-EMF-Images/Output/Slide_Image_5.emf new file mode 100644 index 0000000..0a8166b Binary files /dev/null and b/Images/Extract-EMF-Images-In-PPTX/.NET/Extract-EMF-Images/Output/Slide_Image_5.emf differ diff --git a/Images/Extract-EMF-Images-In-PPTX/.NET/Extract-EMF-Images/Output/gitkeep.txt b/Images/Extract-EMF-Images-In-PPTX/.NET/Extract-EMF-Images/Output/gitkeep.txt new file mode 100644 index 0000000..5f28270 --- /dev/null +++ b/Images/Extract-EMF-Images-In-PPTX/.NET/Extract-EMF-Images/Output/gitkeep.txt @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/Images/Extract-EMF-Images-In-PPTX/.NET/Extract-EMF-Images/Program.cs b/Images/Extract-EMF-Images-In-PPTX/.NET/Extract-EMF-Images/Program.cs new file mode 100644 index 0000000..e86f590 --- /dev/null +++ b/Images/Extract-EMF-Images-In-PPTX/.NET/Extract-EMF-Images/Program.cs @@ -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); + } + } + } + } + } + + /// + /// Processes a shape: saves EMF images and recurses through group shapes. + /// + 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); + } + } + } + + /// + /// Saves EMF image from the picture shape. + /// + 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); + } + } + + /// + /// Checks whether the given byte[] looks like an EMF file. + /// + 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; + } +} \ No newline at end of file