我正在制作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页插入所有图像,那么它的工作完全正常。 我很想知道上面代码中的错误是什么。 任何帮助将受到高度赞赏。
答案 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);
}
}
}
}