Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Copy Enhanced Metafile from clipboard and save it as an image

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.

like image 540
trailblazer Avatar asked Sep 03 '13 21:09

trailblazer


People also ask

How do I copy an enhanced metafile?

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.

How do you paste special image enhanced metafile?

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).

What is picture enhanced metafile?

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.

How do you paste as an enhanced metafile in Powerpoint for Mac?

To paste in Powerpoint, right click and select Picture or select paste special and choose the enhanced metafile format.


2 Answers

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
    }
}
like image 114
Rubens Farias Avatar answered Sep 30 '22 11:09

Rubens Farias


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);
 }
like image 40
Szymon Avatar answered Sep 30 '22 11:09

Szymon