How to read object images from MS-Word using Interop

Obtaining Image from ms-word gave me headache for  a week. MS-Word contains two type of shapes: Shape and InlineShapes.

Shape refers to the objects inserted as object like Chemical Equations, Microsoft Equations, while inline shapes refer to images inserted, drawings etc. Following code provides an way to save both such files.

An updated version of the code will be republished later.

using System.Drawing;

using System.Drawing.Imaging;

using System.IO;

using System.Threading;

using System.Windows.Forms;

using MyProject.Common;

using Microsoft.Office.Interop.Word;

using Application = Microsoft.Office.Interop.Word.Application;

public class InteropOfficeHelper

{

public void Main(string filePath, int index, string savedFilePath, bool isInline)

{

// Open a doc file

var wordApplication = new Application();

var document = wordApplication.Documents.Open(filePath);

//if not inline and other shapes

if (!isInline)

{

if (index <= wordApplication.ActiveDocument.Shapes.Count)

{

var shapeId = index;

var thread = new Thread(() => SaveShapeToFile(shapeId, wordApplication, savedFilePath));

thread.SetApartmentState(ApartmentState.STA);

thread.Start();

thread.Join();

}

}

//if inliine images

else

{

if (index <= wordApplication.ActiveDocument.InlineShapes.Count)

{

var shapeId = index;

var thread = new Thread(() => SaveInlineShapeToFile(shapeId, wordApplication, savedFilePath));

thread.SetApartmentState(ApartmentState.STA);

thread.Start();

thread.Join();

}

}

// Close word

wordApplication.Quit();

}

protected static void SaveInlineShapeToFile(int inlineShapeId, Application wordApplication, string savedFilePath)

{

// 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(savedFilePath);

}

}

}

protected static void SaveShapeToFile(int shapeId, Application wordApplication, string savedFilePath)

{

// Get the shape, select, and copy it to the clipboard

var shape = wordApplication.ActiveDocument.Shapes[shapeId];

shape.Select();

wordApplication.Selection.Copy();

// Check data is in the clipboard

var data = Clipboard.GetDataObject();

if (data != null)

{

// Check if the data conforms to a bitmap format

if (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(savedFilePath);

}

else if (data.GetDataPresent(“PNG”))

{

var byteArray = StreamHelper.ReadToEnd((Stream)data.GetData(“PNG”));

using (var stream = new MemoryStream(byteArray))

{

using (var newImage = Image.FromStream(stream))

{

newImage.Save(savedFilePath, ImageFormat.Png);

}

}

}

else if (data.GetDataPresent(“GIF”))

{

var byteArray = StreamHelper.ReadToEnd((Stream)data.GetData(“GIF”));

using (var stream = new MemoryStream(byteArray))

{

using (var newImage = Image.FromStream(stream))

{

newImage.Save(savedFilePath, ImageFormat.Gif);

}

}

}

}

}

}

Leave a comment