2017-03-24 13 views
0

私はdocファイルから画像を抽出し、すべての画像をPictureboxに表示するはずのC#アプリケーションを作っています。Microsoft.Office.Interop.Wordを使用してC#でdocファイルから画像を抽出する。

WRONG SOLUTION

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ページにすべての画像を挿入すると、それは完全に正常に動作します。 私は上記のコードの間違いが何であるか知りたいです。 ご協力いただければ幸いです。ここで

答えて

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

    } 
}