【问题标题】:Extracting Images from doc file in c# using using Microsoft.Office.Interop.Word;使用 Microsoft.Office.Interop.Word 从 c# 中的 doc 文件中提取图像;
【发布时间】:2017-03-24 15:59:53
【问题描述】:

我正在制作 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;
    }

问题是,如果我在我的 doc 文件的第 2 页上插入图像,那么 img 会变为 null。如果我在第 1 页中插入所有图像,那么它工作得非常好。 我很想知道上述代码中的错误是什么。 任何帮助将不胜感激。

【问题讨论】:

    标签: c# image winforms office-interop


    【解决方案1】:

    这是正确的解决方案:

        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;
        }
    

    【讨论】:

      【解决方案2】:

      由于您正在处理内联形状,您还可以考虑使用关联范围对象的属性 .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);
                  }
              }
      
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2022-06-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-07-12
        相关资源
        最近更新 更多