使用Microsoft.Office.Interop.Word从c#中的doc文件中提取图像;

时间:2017-03-24 15:59:53

标签: c# image winforms office-interop

我正在制作C#应用程序,它应该从doc文件中提取图像并在Pictureboxes中显示所有提取的图像。我有以下代码:

错误的解决方案

using Microsoft.Office.Interop.Word;
  public IDataObject ImageData { get; private set; }

    public List<Image> GetImages(Document doc)
    {
        List<Image> image = new List<Image>();
        foreach (InlineShape shape in doc.InlineShapes)
        {

            shape.Range.Select();
            if (shape.Type == WdInlineShapeType.wdInlineShapePicture)
            {
                doc.ActiveWindow.Selection.Range.CopyAsPicture();
                ImageData = Clipboard.GetDataObject();
                Image img = (Image)ImageData.GetData(DataFormats.Bitmap);


                image.Add(img);
                /*
                bmp.Save("C:\\Users\\Akshay\\Pictures\\bitmaps\\test" + i.ToString() + ".bmp");
                */
            }
        }

        return image;
    }

问题是,如果我在第2页上插入我的doc文件中的图像,那么img将变为null。如果我在第1页插入所有图像,那么它的工作完全正常。 我很想知道上面代码中的错误是什么。 任何帮助将受到高度赞赏。

2 个答案:

答案 0 :(得分:0)

以下是正确的解决方案:

    using Microsoft.Office.Interop.Word;
    public List<Image> GetImages(Document doc,Microsoft.Office.Interop.Word.Application app)
    {
        List<Image> images = new List<Image>();
        for (var i = 1; i <= app.ActiveDocument.InlineShapes.Count; i++)
        {
             var inlineShapeId = i;



             images.Add(SaveInlineShapeToFile(inlineShapeId, app));

            // STA is needed in order to access the clipboard

        }

         return images;
    }

        private Image SaveInlineShapeToFile(int inlineShapeId, Microsoft.Office.Interop.Word.Application app)
    {
        var inlineShape = app.ActiveDocument.InlineShapes[inlineShapeId];
        inlineShape.Select();
       app.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
                Image image = (Image)data.GetData(DataFormats.Bitmap, true);
                return image;
            }
        }
        return null;
    }

答案 1 :(得分:0)

由于您正在处理内联形状,您还可以考虑使用相关范围对象的属性.EnhMetaFileBits。这样可以避免使用剪贴板,但图像质量可能会稍差,所以这取决于您的要求:

var document = app.ActiveDocument;
var imageShape = document.InlineShapes[1];

imageShape.SaveAsImage(Path.Combine(document.Path, "image.jpg"), ImageFormat.Jpeg);

public static class ImageSaving
{
    //Based on:http://stackoverflow.com/questions/6512392/how-to-save-word-shapes-to-image-using-vba
    public static void SaveAsImage(this Word.InlineShape inlineShape, string saveAsFileName, ImageFormat imageFormat)
    {
        Directory.CreateDirectory(Path.GetDirectoryName(saveAsFileName));
        var range = inlineShape.Range;
        var bytes = (byte[])range.EnhMetaFileBits;
        //This byte array could simply be saved to a .wmf-file with File.WriteAllBytes()

        using (var stream = new MemoryStream(bytes))
        //Code for resizing based on:  http://stackoverflow.com/questions/7951734/an-unclear-converted-image-wmf-to-png
        using (var metaFile = new Metafile(stream))
        {
            var header = metaFile.GetMetafileHeader();

            //Calculate the scale based on the shape width
            var scale = header.DpiX / inlineShape.Width;

            var width = scale * metaFile.Width / header.DpiX * 100;

            var height = scale * metaFile.Height / header.DpiY * 100;

            using (var bitmap = new Bitmap((int)width, (int)height))
            using (var graphics = Graphics.FromImage(bitmap))
            {
                graphics.Clear(Color.White);
                graphics.ScaleTransform(scale, scale);
                graphics.DrawImage(metaFile, 0, 0);

                //At this point you could do something else with the bitmap than save it
                bitmap.Save(saveAsFileName, imageFormat);
            }
        }

    }
}