【发布时间】:2020-08-14 08:58:13
【问题描述】:
我正在尝试使用 C# 将嵌入的 shape 保存为图像。
如果对象嵌入为实际图像 (WMF/JPEG),我可以毫无问题地检索图像,但是当对象是嵌入形状或在 Word 中显示为图像的 OLE 对象时,我似乎无法提取或检索然后将所述对象复制到剪贴板或保存所述图像。
这是我当前的代码示例;要么对象为空,要么出现以下错误:
System.Runtime.InteropServices.ExternalException: 'A generic error occurred in GDI+.'
感谢任何帮助。谢谢
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Forms;
using System.Windows.Media;
using System.Windows.Media.Imaging;
namespace ImageMagickSandboxWinForms
{
public partial class frmMain : Form
{
public frmMain()
{
InitializeComponent();
}
public static BitmapSource ConvertBitmap(Bitmap source)
{
return System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
source.GetHbitmap(),
IntPtr.Zero,
Int32Rect.Empty,
BitmapSizeOptions.FromEmptyOptions());
}
public static Bitmap BitmapFromSource(BitmapSource bitmapsource)
{
Bitmap bitmap;
using (var outStream = new MemoryStream())
{
BitmapEncoder enc = new BmpBitmapEncoder();
enc.Frames.Add(BitmapFrame.Create(bitmapsource));
enc.Save(outStream);
bitmap = new Bitmap(outStream);
}
return bitmap;
}
private void button1_Click(object sender, EventArgs e)
{
string physicsDocLocation = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop));
physicsDocLocation += @"\[Doc path Here].docx";
var wordApp = new Microsoft.Office.Interop.Word.Application();
var wordDoc = wordApp.Documents.Open(physicsDocLocation);
int iCount = wordDoc.InlineShapes.Count;
for (int i = 1; i < (wordDoc.InlineShapes.Count + 1); i++)
{
var currentInlineShape = wordDoc.InlineShapes[i];
currentInlineShape.Range.Select();
wordDoc.ActiveWindow.Selection.Range.Copy();
BitmapSource clipBoardImage = System.Windows.Clipboard.GetImage();
Bitmap bmpClipImage = BitmapFromSource(clipBoardImage);
string finalPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), @"TestConversions");
finalPath += @"\" + Guid.NewGuid().ToString() + ".jpg";
using (MemoryStream memory = new MemoryStream())
{
using (FileStream fs = new FileStream(finalPath, FileMode.Create, FileAccess.ReadWrite))
{
bmpClipImage.Save(memory, ImageFormat.Jpeg); <<<---- Error happens here.
byte[] bytes = memory.ToArray();
fs.Write(bytes, 0, bytes.Length);
}
}
}
wordDoc.Close();
wordApp.Quit();
}
}
}
【问题讨论】:
-
您能否提供更多关于这些嵌入对象类型的信息,如果可能,它们是如何创建的?如果没有这些信息,就不可能测试哪种方法可行。嵌入式 OLE 对象是创建它的程序的“子”,必须访问该服务器才能“获取”它。一般来说,您可能会看到右键单击是否可以选择从嵌入式转换为其他内容。复制(剪切)然后特别粘贴回纯图像格式也可能是一种可能性。
-
@CindyMeister,所以源文档有数学方程和相关图表,我假设它们来自微软的数学方程编辑器(或类似的东西)。奇怪的是,通过上述方法可以轻松地将某些方程式复制为剪贴板中的图像,而其他方程式则不能。
-
@CindyMeister,此外,如果我手动复制/粘贴,方程式会按预期作为图像出现。希望这会有所帮助。
-
然后使用 PasteSpecial 执行此操作,以便您可以指定粘贴时使用的格式。并且应该将其他信息真正编辑到问题中,而不是留在评论中。
标签: c# ms-word office-interop data-conversion