I am using the follwing C# code to copy the image from clipboard.
if (Clipboard.ContainsData(System.Windows.DataFormats.EnhancedMetafile))
{
/* taken from http://social.msdn.microsoft.com/Forums/windowsdesktop/en-US/a5cebe0d-eee4-4a91-88e4-88eca9974a5c/excel-copypicture-and-asve-to-enhanced-metafile*/
var img = (System.Windows.Interop.InteropBitmap)Clipboard.GetImage();
var bit = Clipboard.GetImage();
var enc = new System.Windows.Media.Imaging.JpegBitmapEncoder();
var stream = new FileStream(fileName + ".bmp", FileMode.Create);
enc.Frames.Add(BitmapFrame.Create(bit));
enc.Save(stream);
}
I took this snippet from here. The control does go in the if condition. Clipboard.GetImage()
returns null. Can someone please suggest what is going wrong in here?
I have also tried the following snippet
Metafile metafile = Clipboard.GetData(System.Windows.DataFormats.EnhancedMetafile) as Metafile;
Control control = new Control();
Graphics grfx = control.CreateGraphics();
MemoryStream ms = new MemoryStream();
IntPtr ipHdc = grfx.GetHdc();
grfx.ReleaseHdc(ipHdc);
grfx.Dispose();
grfx = Graphics.FromImage(metafile);
grfx.Dispose();
This too doesn't work.
In Word, choose Edit > Paste Special and choose to paste as a Picture (Enhanced Metafile). In Excel, click the chart once and be sure it shows 8 small black square markers on the edge. Do Edit > Copy, or just ctrl-c. In Word, do Edit > Paste, or just ctrl-v.
Paste Special shortcut For example, people often ask me: What is the Paste as Enhanced Metafile format shortcut? The answer is the Paste Special shortcut (CTRL + ALT + V) and selecting the Metafile format (described below).
EMF, acronym of “Enhanced MetaFile” is an image format most used in Windows OS for printing purposes. This device independent format was developed as an improved version of Windows Metafile (WMF) format. It's is a 32 bit format that contains more color and high quality graphics.
To paste in Powerpoint, right click and select Picture or select paste special and choose the enhanced metafile format.
You can use user32.dll
via p/invoke as below:
public const uint CF_METAFILEPICT = 3;
public const uint CF_ENHMETAFILE = 14;
[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
public static extern bool OpenClipboard(IntPtr hWndNewOwner);
[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
public static extern bool CloseClipboard();
[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
public static extern IntPtr GetClipboardData(uint format);
[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
public static extern bool IsClipboardFormatAvailable(uint format);
Now, you can read your metafile:
Metafile emf = null;
if (OpenClipboard(IntPtr.Zero))
{
if (IsClipboardFormatAvailable(CF_ENHMETAFILE))
{
var ptr = GetClipboardData(CF_ENHMETAFILE);
if (!ptr.Equals(IntPtr.Zero))
emf = new Metafile(ptr, true);
}
// You must close ir, or it will be locked
CloseClipboard();
}
My original requirement involves some more handling of that metafile, so I create a MemoryStream
:
using (var graphics = Graphics.FromImage(new Bitmap(1,1,PixelFormat.Format32bppArgb)))
{
var hdc = graphics.GetHdc();
using (var original = new MemoryStream())
{
using (var dummy = Graphics.FromImage(new Metafile(original, hdc)))
{
dummy.DrawImage(emf, 0, 0, emf.Width, emf.Height);
dummy.Flush();
}
graphics.ReleaseHdc(hdc);
// do more stuff
}
}
The following code will work. You can change the format of the image you save if you want.
if (Clipboard.ContainsImage())
{
Image image = Clipboard.GetImage();
image.Save(@"c:\temp\image.jpg", System.Drawing.Imaging.ImageFormat.Jpeg);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With