0

So I have figured out how to replace pictures with text in word using this link

But now I need to export pictures from word to a folder. And I'm guessing whenever I find a picture which is a object(type s=Microsoft.Office.Interop.Word.WdInlineShapeType.wdInlineShapePicture) I should do something with it... But I can't find the option: s.saveAsPicture(@"C:\pic.jpg");

Community
  • 1
  • 1
Greeed
  • 418
  • 2
  • 8
  • 29
  • There is no such option. You can get it to the clipboard and then do what you want with it, http://social.msdn.microsoft.com/Forums/en-SG/vsto/thread/1bf630ad-70a3-4e04-9399-67c64043782f – Hans Passant Sep 05 '12 at 19:39
  • How do you feel about saving the whole document as html? This will save all the images in a separate folder. It seems to be what the MVPs recommend. – Fionnuala Sep 05 '12 at 20:09
  • @Remou very unintellectual solution, that would only work if we wouldn't have to perform any other operations with the word document... However in my case i have to compare pictures, analyze them replace them so I can't brute force this solution – Greeed Dec 31 '12 at 06:23

1 Answers1

5

Your question might be a possible duplicate of: extract image from word file

However, based on my previous answer to your question regarding how to programmatically compare an external image with inline shapes in Word ( see Compare picture in Word file and in a folder? ) - you can make a couple of simple adjustments and use almost the exact same sample code to export each inline shape to a folder instead of comparing the shapes with another image.

To illustrate I have made the necessary adjustments for you and provided the source code below. Again, the application is a C# console application based on .NET 4.5, Microsoft Office Object Library version 15.0, and Microsoft Word Object Library version 15.0.

And like before, I have included references in the source code such that you can see which sources I have based my solution on ( and such that the sources gets the credit they deserve ;) )

using System;
using System.Drawing;
using System.Threading;
using System.Windows.Forms;
using Application = Microsoft.Office.Interop.Word.Application;

namespace WordDocStats
{
    class Program
    {
        // General idea is based on: https://stackoverflow.com/a/7937590/700926
        static void Main()
        {
            // Open a doc file
            var wordApplication = new Application();
            var document = wordApplication.Documents.Open(@"C:\Users\Username\Documents\document.docx");

            // For each inline shape, export it to a file
            // By inspection you can see that the first inline shape have index 1 ( and not zero as one might expect )
            for (var i = 1; i <= wordApplication.ActiveDocument.InlineShapes.Count; i++)
            {
                // closure
                // http://confluence.jetbrains.net/display/ReSharper/Access+to+modified+closure
                var inlineShapeId = i; 

                // parameterized thread start
                // https://stackoverflow.com/a/1195915/700926
                var thread = new Thread(() => SaveInlineShapeToFile(inlineShapeId, wordApplication));

                // STA is needed in order to access the clipboard
                // https://stackoverflow.com/a/518724/700926
                thread.SetApartmentState(ApartmentState.STA);
                thread.Start();
                thread.Join();
            }

            // Close word
            wordApplication.Quit();
            Console.ReadLine();
        }

        // General idea is based on: https://stackoverflow.com/a/7937590/700926
        protected static void SaveInlineShapeToFile(int inlineShapeId, Application wordApplication)
        {
            // Get the shape, select, and copy it to the clipboard
            var inlineShape = wordApplication.ActiveDocument.InlineShapes[inlineShapeId];
            inlineShape.Select();
            wordApplication.Selection.Copy();

            // Check data is in the clipboard
            if (Clipboard.GetDataObject() != null)
            {
                var data = Clipboard.GetDataObject();

                // Check if the data conforms to a bitmap format
                if (data != null && data.GetDataPresent(DataFormats.Bitmap))
                {
                    // Fetch the image and convert it to a Bitmap
                    var image = (Image) data.GetData(DataFormats.Bitmap, true);
                    var currentBitmap = new Bitmap(image);

                    // Save the bitmap to a file
                    currentBitmap.Save(@"C:\Users\Username\Documents\" + String.Format("img_{0}.png", inlineShapeId));
                }
            }
        }
    }
}
Community
  • 1
  • 1
Lasse Christiansen
  • 10,205
  • 7
  • 50
  • 79
  • I followed this answer and it worked great the first time. But now I'm experiencing something weird: the Clipboard contains data, but it won't let me get the data in any of the available formats. Like I said, bitmap worked the first time I used this. But now data.GetDataPresent(...) with any DataFormats.SOMETHING always returns false. Any idea what could be happening? – Jake Smith Dec 27 '13 at 23:42
  • This is super old, but this won't work if Word is in the middle of opening a context menu for the image in question. – Chris May 07 '16 at 20:38
  • Hello, how can I achieve this in .Net Core 2.2? There is no clipboard mechanism there, and I need to extract images from Word app, do you have any ideas? Many thanks. – Yunus May 13 '20 at 12:40