我正试图保存一个嵌入的 形状 作为一个图像使用C#。
如果对象是嵌入作为一个实际的图像(WMFJPEG),我可以检索图像没有问题,但当对象是一个嵌入式形状或OLE对象,显示在Word中的图像,我似乎不能提取或检索所述对象,然后要么复制到剪贴板或保存所述图像。
这是我当前的代码示例;要么对象是空的,要么我得到以下错误。
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();
}
}
}
我有这些代码在我的图书馆,不知道我在哪里找到的,但希望你为你做的工作:我使用Clippboard捕捉不同的图像,Jus t dont forget,线程是需要访问剪贴板。
for (var i = 1; i <= wordApplication.ActiveDocument.InlineShapes.Count; i++)
{
var inlineShapeId = i;
var thread = new Thread(() => SaveInlineShapeToFile(inlineShapeId, wordApplication));
// STA is needed in order to access the clipboard
// https://stackoverflow.com/a/518724/700926
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
thread.Join();
}
// General idea is based on: https://stackoverflow.com/a/7937590/700926
protected static void SaveInlineShapeToFile(int inlineShapeId, Application wordApplication)
{
// Get the shape, select, and copy it to the clipboard
var inlineShape = wordApplication.ActiveDocument.InlineShapes[inlineShapeId];
inlineShape.Select();
wordApplication.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
var image = (Image) data.GetData(DataFormats.Bitmap, true);
var currentBitmap = new Bitmap(image);
// Save the bitmap to a file
currentBitmap.Save(@"C:\Users\Username\Documents\" + String.Format("img_{0}.png", inlineShapeId));
}
}
}
如果你使用的是Winform或WPF,剪贴板对图像的作用是不同的。
if (Clipboard.ContainsImage())
{
// ImageUIElement.Source = Clipboard.GetImage(); // does not work
System.Windows.Forms.IDataObject clipboardData = System.Windows.Forms.Clipboard.GetDataObject();
if (clipboardData != null)
{
if (clipboardData.GetDataPresent(System.Windows.Forms.DataFormats.Bitmap))
{
System.Drawing.Bitmap bitmap = (System.Drawing.Bitmap)clipboardData.GetData(System.Windows.Forms.DataFormats.Bitmap);
ImageUIElement.Source = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(bitmap.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty,BitmapSizeOptions.FromEmptyOptions());
Console.WriteLine("Clipboard copied to UIElement");
}
}
}
如果由于格式翻译中的一个错误而导致其无法正常工作,那么在剪贴板上会出现以下情况。解决办法 . 因此,它不常见,但它很容易理解使用 "DeviceIndependentBitmap "的逻辑。