all groups > dotnet drawing api > april 2008 >
You're in the

dotnet drawing api

group:

Bitmap + Clipboard + Transparency = Blue Background?


Bitmap + Clipboard + Transparency = Blue Background? mcse3010
4/11/2008 9:20:07 AM
dotnet drawing api: Hey folks, I think this is my first time asking a question here, so please go
easy on me

I have an application wherein I render a transparent bitmap (to be specific
-- a chart with a transparent background).... When I do, I then try to copy
it to the clipboard using:


bmp.Save(filename); // Save to FS
Clipboard.SetImage(bmp); // Save to Clipboard


Now if I open Excel, and click Paste (from the clipboard), I end up with a
copy of my chart with this lovely blue background wherever the transparency
color was.

If I, instead, use Excel's Insert->Image->From File, the chart's
transparency is preserved... (same bitmap as above, just one is saved to file
system, the other is copied via clipboard)

Am I copying the bitmap to clipboard incorrectly, are transparent bitmaps
supported cross-application this way? (I suspect they are, because I can copy
that same bitmap in excel (CTRL+C) and paste it into powerpoint without loss
of transparency)

Re: Bitmap + Clipboard + Transparency = Blue Background? mcse3010
4/11/2008 11:51:03 AM
The only way I've found to specify a specific format (like PNG) is to save it
physically to disk, and specify the format using the ImageFormat
enumeration.. how would I copy this to the clipboard in PNG format?

TIA
Chadwick

[quoted text, click to view]
Re: Bitmap + Clipboard + Transparency = Blue Background? mcse3010
4/11/2008 1:20:01 PM
FANTASTIC!

Both of you guys have seriously solved a problem that I've had for quite a
while... thank you SO Much!

[quoted text, click to view]
Re: Bitmap + Clipboard + Transparency = Blue Background? mcse3010
4/11/2008 2:21:01 PM
Don't you just hate it when you speak too soon? I should have asked both
questions, instead of assuming the same solution would solve both problems I
had.

The other issue I had was in attempts to drag and drop the same image I was
copying and pasting before. Now excel (and powerpoint) recognize the
IDataObject, the drag and drop curiously enough doesn't?

Any pointers on where to look? I have looked at the IDataObject interface
and searched google, most of what seems relevant is all in unmanaged C++....

TIA

[quoted text, click to view]
Re: Bitmap + Clipboard + Transparency = Blue Background? mcse3010
4/11/2008 3:25:01 PM
Sorry I should have been more clear... I want to drag from a picturebox in
..NET onto Excel and drop the PNG that we generated with the clipboard...
something like:

IDataObject dataObj = CreateDataObjectFromBmp(bmp);
this.DoDragDrop(dataObj, DragDropEffects.All);

but the drop onto excel doesn't work the way the paste did.... I can do the
DoDragDrop on the bmp object, but then I'm back to the blue background on
that...

How can I do the dragdrop while preserving the transparency as with the
clipboard and the DataObject?

Thanks

[quoted text, click to view]
Re: Bitmap + Clipboard + Transparency = Blue Background? Michael Phillips, Jr.
4/11/2008 3:28:17 PM
[quoted text, click to view]

MemoryStream ms = new MemoryStream();
bmp.Save(ms, ImageFormat.Png);
IDataObject dataObject = new DataObject();
dataObject.SetData("PNG", false, ms);
System.Windows.Forms.Clipboard.SetDataObject(dataObject, false);

[quoted text, click to view]

Re: Bitmap + Clipboard + Transparency = Blue Background? mcse3010
4/11/2008 4:43:00 PM
Thanks for the info... for now I will trap the end of the drag drop event,
open the shape using automation and reload the shape from file...

Thanks

[quoted text, click to view]
Re: Bitmap + Clipboard + Transparency = Blue Background? Michael Phillips, Jr.
4/11/2008 6:09:39 PM
The DataObject in .Net implements the IOleDataObject and IDataObject
interfaces.

You can query to see if a particular format is supported by the DataObject
with GetDataPresent and use GetData to retrieve it.

[quoted text, click to view]

Re: Bitmap + Clipboard + Transparency = Blue Background? Bob Powell [MVP]
4/11/2008 7:09:22 PM
This is because a saved bitmap has no transparency information as it's 24
bits per pixel. Try copying to the clipboard in a specific format and / or
saving as a PNG that has transparency.

--
--
Bob Powell [MVP]
Visual C#, System.Drawing

Ramuseco Limited .NET consulting
http://www.ramuseco.com

Find great Windows Forms articles in Windows Forms Tips and Tricks
http://www.bobpowell.net/tipstricks.htm

Answer those GDI+ questions with the GDI+ FAQ
http://www.bobpowell.net/faqmain.htm

All new articles provide code in C# and VB.NET.
Subscribe to the RSS feeds provided and never miss a new article.


[quoted text, click to view]
Re: Bitmap + Clipboard + Transparency = Blue Background? Bob Powell [MVP]
4/11/2008 7:09:54 PM
This is because a saved bitmap has no transparency information as it's 24
bits per pixel. Try copying to the clipboard in a specific format and / or
saving as a PNG that has transparency.

--
--
Bob Powell [MVP]
Visual C#, System.Drawing

Ramuseco Limited .NET consulting
http://www.ramuseco.com

Find great Windows Forms articles in Windows Forms Tips and Tricks
http://www.bobpowell.net/tipstricks.htm

Answer those GDI+ questions with the GDI+ FAQ
http://www.bobpowell.net/faqmain.htm

All new articles provide code in C# and VB.NET.
Subscribe to the RSS feeds provided and never miss a new article.


[quoted text, click to view]
Re: Bitmap + Clipboard + Transparency = Blue Background? Michael Phillips, Jr.
4/11/2008 7:34:16 PM
[quoted text, click to view]

MemoryStream ms = new MemoryStream();
bmp.Save(ms, ImageFormat.Png);
IDataObject dataObject = new DataObject();
dataObject.SetData("PNG", false, ms);
this.DoDragDrop(dataObject, DragDropEffects.All);

Only Office 2007 understands images with transparency. As long as, you
create a DataObject and place a PNG in it, then Office 2007 will recognize
the "PNG" format and display it with transparency.

I have not tried to drag an alpha channel image out of a picturebox. It is
possible that it is not supported without extra work.


[quoted text, click to view]

Re: Bitmap + Clipboard + Transparency = Blue Background? Michael Phillips, Jr.
4/14/2008 8:59:41 AM
Try using the clipbrd.exe utility that is present in all versions of
Windows.

This clipboard viewer is invaluable for testing your code for compliance
with the clipboard API.

If you see the "PNG" format with this utility, try a paste with Word 2007 or
MS Paint.

I do not know if Paint.Net supports the "PNG" clipboard format.

[quoted text, click to view]

Re: Bitmap + Clipboard + Transparency = Blue Background? Christopher Ireland
4/14/2008 11:12:13 AM
Hello Michael,

[quoted text, click to view]

This code looks great and could be just what I need as well, however, I
can't get it to work as I think it should do. When I copy my bitmap onto the
clipboard, Paint.NET tells me "The clipboard doesn't contain an image". Is
this a bug in Paint.NET ('normal' paint does nothing when the image is
pasted in .. no error message and no image) or is it a problem with my code
below? The file saved to disk in the example, mycontrol.png, looks fine in
Paint.NET with the checker-board transparency color present. Any thoughts
gratefully received!

namespace WindowsFormsApplication1
{
public partial class Form3 : Form
{
public Form3()
{
InitializeComponent();
InitializeControl();
}

private void InitializeControl()
{
myControl1 = new MyControl();
myControl1.Location = new System.Drawing.Point(40, 12);
myControl1.Size = new System.Drawing.Size(600, 400);
Controls.Add(myControl1);

myControl1.BackColor = Color.Transparent;
myControl1.AString = "My Control";

myControl1.Save(@"C:\temp\mycontrol.png");
}

private MyControl myControl1;

private void button1_Click(object sender, EventArgs e)
{
myControl1.CopyToClipboard();
}
}

public class MyControl : Control
{
public MyControl()
: base()
{
SetStyle(ControlStyles.OptimizedDoubleBuffer, false);
SetStyle(ControlStyles.SupportsTransparentBackColor, true);
}

protected override void OnPaint(PaintEventArgs e)
{
Rectangle rect = ClientRectangle;
rect.Inflate(-1, -1);
e.Graphics.DrawString(AString, new Font("Verdana", 12), Brushes.Black,
new PointF(10, 10));
e.Graphics.DrawRectangle(Pens.Red, rect);
}

public string AString { get; set; }

public void CopyToClipboard()
{
Rectangle rect = ClientRectangle;
Bitmap b = new Bitmap(rect.Width, rect.Height);
DrawToBitmap(b, rect);

MemoryStream ms = new MemoryStream();
b.Save(ms, Encoder, EncoderParams);
IDataObject dataObject = new DataObject();
dataObject.SetData("PNG", false, ms);
Clipboard.Clear();
Clipboard.SetDataObject(dataObject, false);
}

public void Save(string path)
{
Rectangle rect = ClientRectangle;
Bitmap bmp = new Bitmap(rect.Width, rect.Height);
DrawToBitmap(bmp, rect);
bmp.Save(path, Encoder, EncoderParams);
}

private ImageCodecInfo Encoder
{
get { return GetEncoderInfo(Format.Guid); }
}

private ImageFormat Format
{
get { return System.Drawing.Imaging.ImageFormat.Png; }
}

private ImageCodecInfo GetEncoderInfo(Guid g)
{
ImageCodecInfo[] encoders = ImageCodecInfo.GetImageEncoders();
for (int t = 0; t < encoders.Length; t++)
{
if (encoders[t].FormatID == g)
return encoders[t];
}
return null;
}

private EncoderParameters EncoderParams
{
get { return null; }
}
}
}

--
Thank you,

Christopher Ireland
http://shunyata-kharg.doesntexist.com

"All understanding begins with our not accepting the world as it appears."
Alan C. Kay

Re: Bitmap + Clipboard + Transparency = Blue Background? Michael Phillips, Jr.
4/14/2008 11:37:12 AM
MS Paint does not recognize the "PNG" clipboard format.

However, Office 2007 does regognize the "PNG" clipboard format.

I am able to past the "PNG" clipboard format with no problems.

You can either write code to paste the "PNG" clipboard format into your own
test form or try another application such as Word2007, Excel2007, etc. to
test that you placed the clipboard format on to the clipboard correctly.

[quoted text, click to view]

Re: Bitmap + Clipboard + Transparency = Blue Background? Michael Phillips, Jr.
4/14/2008 2:19:49 PM
Your code works perfectly.

If you wish to verify the image, then paste the image into a PictureBox
control and display it or simply save it to a new file and compare to the
original.

System.Windows.Forms.IDataObject iData = Clipboard.GetDataObject();
if ( null != iData)
{
if ( iData.GetDataPresent("PNG", false))
{
MemoryStream strm = (MemoryStrem)iData.GetData("PNG");
if ( null != strm)
{
// display in a PictureBox control
PictureBox1.Image = (Bitmap)Image.FromStream(strm,true);
// and/or save it
Image image = (Bitmap)Image.FromStream(strm,true);
image.Save(@"c:\temp\ControlPasteTest.png", ImageFormat.Png);
}
}
}


[quoted text, click to view]

Re: Bitmap + Clipboard + Transparency = Blue Background? Christopher Ireland
4/14/2008 3:18:23 PM
Michael,

Thank you for your reply!

[quoted text, click to view]

Using the code I sent in my previous message, clipbrd.exe gave me the
following error:
"ClipBook Viewer cannot display the information in its current format. To
view the information, try pasting it into a document."

[quoted text, click to view]

When I mentioned "normal Paint" in my last message, I meant MS Paint. MS
Paint neither gives me an error nor displays the image when I try to paste
the clipboard contents of the code I posted.

[quoted text, click to view]

No, neither do I!

--
Thank you,

Christopher Ireland

Re: Bitmap + Clipboard + Transparency = Blue Background? Michael Phillips, Jr.
4/14/2008 4:47:16 PM
[quoted text, click to view]

An application chooses which, if any, clipboard formats it wishes to
support.

You do not have any control as to how an application will choose a
particular clipboard format.

The best rule is to place as many formats as you can on the clipboard and
hope that an application will choose one of the formats that you placed on
the clipboard.

I usually place the following .Net clipboard formats on the clipboard:
"Bitmap"
"Palette"
"DeviceIndependentBitmap"
"Format17"
"MetaFilePict"
"EnhancedMetafile"
"PNG"
"JPG"
"TIFF"
"GIF"

Most applications will support one or more of the above clipboard formats.

For transparent images, I use "PNG" and the bitmap varieties. I
specifically scan the image for the presence of a valid alpha channel.

[quoted text, click to view]

Re: Bitmap + Clipboard + Transparency = Blue Background? Christopher Ireland
4/14/2008 5:49:35 PM
Michael,

Thanks again for your time!

[quoted text, click to view]

I see.

[quoted text, click to view]

clipbrd.exe should also recognise the "PNG" clipboard format, even without
Office2007 installed (which is my case here), shouldn't it?

[quoted text, click to view]

Yes, I did write some code to test which doesn't seem to work here. Would
you be so kind as to test the code at your end? Here it is again (this is
simple, complete code which will run "as-is"):

namespace WindowsFormsApplication1
{
public partial class Form3 : Form
{
public Form3()
{
InitializeComponent();
InitializeControl();
}

private void InitializeControl()
{
myControl1 = new MyControl();
myControl1.Location = new System.Drawing.Point(40, 12);
myControl1.Size = new System.Drawing.Size(600, 400);
Controls.Add(myControl1);

myControl1.BackColor = Color.Transparent;
myControl1.AString = "My Control";

myControl1.Save(@"C:\temp\mycontrol.png");
}

private MyControl myControl1;

private void button1_Click(object sender, EventArgs e)
{
myControl1.CopyToClipboard();
}
}

public class MyControl : Control
{
public MyControl()
: base()
{
SetStyle(ControlStyles.OptimizedDoubleBuffer, false);
SetStyle(ControlStyles.SupportsTransparentBackColor, true);
}

protected override void OnPaint(PaintEventArgs e)
{
Rectangle rect = ClientRectangle;
rect.Inflate(-1, -1);
e.Graphics.DrawString(AString, new Font("Verdana", 12), Brushes.Black,
new PointF(10, 10));
e.Graphics.DrawRectangle(Pens.Red, rect);
}

public string AString { get; set; }

public void CopyToClipboard()
{
Rectangle rect = ClientRectangle;
Bitmap b = new Bitmap(rect.Width, rect.Height);
DrawToBitmap(b, rect);

MemoryStream ms = new MemoryStream();
b.Save(ms, Encoder, EncoderParams);
IDataObject dataObject = new DataObject();
dataObject.SetData("PNG", false, ms);
Clipboard.Clear();
Clipboard.SetDataObject(dataObject, false);
}

public void Save(string path)
{
Rectangle rect = ClientRectangle;
Bitmap bmp = new Bitmap(rect.Width, rect.Height);
DrawToBitmap(bmp, rect);
bmp.Save(path, Encoder, EncoderParams);
}

private ImageCodecInfo Encoder
{
get { return GetEncoderInfo(Format.Guid); }
}

private ImageFormat Format
{
get { return System.Drawing.Imaging.ImageFormat.Png; }
}

private ImageCodecInfo GetEncoderInfo(Guid g)
{
ImageCodecInfo[] encoders = ImageCodecInfo.GetImageEncoders();
for (int t = 0; t < encoders.Length; t++)
{
if (encoders[t].FormatID == g)
return encoders[t];
}
return null;
}

private EncoderParameters EncoderParams
{
get { return null; }
}
}
}

--
Thank you,

Christopher Ireland
http://shunyata-kharg.doesntexist.com

"The only good is knowledge and the only evil is ignorance."
Socrates

Re: Bitmap + Clipboard + Transparency = Blue Background? Christopher Ireland
4/14/2008 9:20:46 PM
Michael,

[quoted text, click to view]

That's great, thank you for taking the time to test it for me!

[quoted text, click to view]

Ok, I haven't had a chance to test it here but I'll assume it will work.

Now for the million dollar question (I bet you can see it coming :-) ... do
you know of a way to replicate this functionality in managed code to allow
the clipboard's contents (transparent png) to be pasted into a much wider
range of documents (other than Visual Studio forms and Office2007
documents)?

--
Thank you,

Christopher Ireland
http://shunyata-kharg.doesntexist.com

"We confess our little faults to persuade people that we have no large
ones."
Francois de La Rochefoucauld

Re: Bitmap + Clipboard + Transparency = Blue Background? Christopher Ireland
4/15/2008 9:25:38 AM
Michael,

[quoted text, click to view]

Many thanks for the tip!

[quoted text, click to view]

Only five of these (Bitmap, Palette, MetaFilePict, EnhancedMetafile, TIFF)
are in the System.Windows.Forms.DataFormats class. Are all the others new
formats types for Office2007 as well?

[quoted text, click to view]

Presumably you mean that you scan for a valid alpha channel when data (an
image) is pasted into your application from the clipboard, right? Is there a
managed code way of using the Bitmap dataformat to reliably copy transparent
PNG images to the clipboard? Most documents I've had experience with seem to
support the Bitmap dataformat and it would be great to hear that you have
been able to copy and paste transparent PNG images using it with managed
code.

--
Thank you,

Christopher Ireland
http://shunyata-kharg.doesntexist.com

"Western science is a major response to minor needs."
Mattheiu Ricard
Re: Bitmap + Clipboard + Transparency = Blue Background? Michael Phillips, Jr.
4/15/2008 9:41:36 AM
[quoted text, click to view]

"DeviceIndependentBitmap" == CF_DIB
"Format17" == CF_DIBV5

The formats below are packed formats using a MemoryStream backed by global
shared memory.
They are not new. Except for "PNG", they were used in all Microsoft's OS's
prior to WindowsXP.

"PNG"
"JPG"
"JFIF"
"TIFF"
"GIF"

Office2007 recognizes all of the clipboard formats that I outlined.

In addition, Office supports OLE1, OLE2 clipboard formats and proprietary
formats.

If you use the clipboard viewer, you will see all of the clipboard formats
that Office presents to the clipboard.

[quoted text, click to view]

Scanning for an alpha channel is only required for bitmaps. The gdiplus
decoder will decode an alpha channel "PNG" automatically.

I use the Format17 clipboard format to represent alpha channel bitmaps.

Per the MSDN documentation, the version 5 BITMAPV5HEADER allows you to
specify a valid alpha channel by filling in the bitfield masks and using
BI_BITFIELDS compression.

One painless method of determining a valid alpha channel is to use
Microsoft's IImageList.GetItemFlags method with the ILIF_ALPHA flag.

It only works with Windows XP and above.

You create an image list and add the bitmap that you wish to test to the
list and use the GetItemFlags with ILIF_ALPHA.

If the returned flag is logically "AND" with the ILIF_ALPHA flag then your
bitmap contains a valid alpha channel.

You just declare the COM Interface and use p-invoke with com interop.

Re: Bitmap + Clipboard + Transparency = Blue Background? Michael Phillips, Jr.
4/15/2008 12:57:08 PM
[quoted text, click to view]

Not all of the image formats that are supported by gdiplus allow for alpha
channel images.

For non alpha channel image formats, you should convert the image to a non
alpha channel format before placing it on the clipboard.

For a 32bpp alpha channel image, simply create a new 32bpp
PixelFormat.Format32bppRgb image and fill the new empty image with the
background color of your choice and then use DrawImage with SourceOver to
alpha blend the alpha bitmap with the new non alpha channel bitmap.

The background color that you choose will replace the alpha channel.

For a jpeg image, after converting to a non alpha channel bitmap, create a
24bpp jpeg version by using DrawImage or saving it to a stream with the jpeg
encoder.

When you are finished, place that image on the clipboard. No more black
backgrounds.

[quoted text, click to view]

Just because the Operating System supports a clipboard format does not mean
that a particular application will use it.

The best way to determine what an application supports is to copy an image
from that application to the clipboard and then examine the supported
clipboard formats with the clipboard viewer utility.

Re: Bitmap + Clipboard + Transparency = Blue Background? Christopher Ireland
4/15/2008 6:33:57 PM
Michael,

Thank you for your continuing help. Your patience is much appreciated.

[quoted text, click to view]

I see.

[quoted text, click to view]

Ok, thank you for the information.

[quoted text, click to view]

Is "PNG" the only alpha channel that is decoded automatically by gdiplus? I
ask because "JPG" doesn't seem to behave in the same way. In the code below,
uncommenting the png lines and commenting the jpg lines produces the desired
result - an image which pastes to and copies from the clipboard preserving
its transparency. However, leaving the code "as-is" produces an image with
the color black where the color transparent should be.

The other issue is that if, when using the code "as-is" below, I comment out
the code that copies the image from the clipboard to file and instead paste
the image into a Word2003 document, nothing is pasted in (no image is
visualised). Clipbrd.exe tells me "ClipBook Viewer cannot display the
information in its current format. To view the information, try pasting it
into a document." From what you said I had understood that at least this
"JPG" clipboard format should be recognised by pre-Office2007 documents.

namespace WindowsFormsApplication1
{
public partial class Form3 : Form
{
public Form3()
{
InitializeComponent();
InitializeControl();
}

private void InitializeControl()
{
myControl1 = new MyControl();
myControl1.Location = new System.Drawing.Point(40, 12);
myControl1.Size = new System.Drawing.Size(600, 400);
Controls.Add(myControl1);

myControl1.BackColor = Color.Transparent;
myControl1.AString = "My Control";

myControl1.CopyToClipboard();

System.Windows.Forms.IDataObject iData = Clipboard.GetDataObject();
if (null != iData)
{
//if (iData.GetDataPresent("PNG", false))
if (iData.GetDataPresent("JPG", false))
{
//MemoryStream strm = (MemoryStream)iData.GetData("PNG");
MemoryStream strm = (MemoryStream)iData.GetData("JPG");
if (null != strm)
{
Image image = (Bitmap)Image.FromStream(strm, true);
//image.Save(@"c:\temp\mycontrol_pasted.png", ImageFormat.Png);
image.Save(@"c:\temp\mycontrol_pasted.jpg", ImageFormat.Jpeg);
}
}
}
}
private MyControl myControl1;
}

public class MyControl : Control
{
public MyControl()
: base()
{
SetStyle(ControlStyles.OptimizedDoubleBuffer, false);
SetStyle(ControlStyles.SupportsTransparentBackColor, true);
}

protected override void OnPaint(PaintEventArgs e)
{
Rectangle rect = ClientRectangle;
rect.Inflate(-1, -1);
e.Graphics.DrawString(AString, new Font("Verdana", 12), Brushes.Black,
new PointF(10, 10));
e.Graphics.DrawRectangle(Pens.Red, rect);
}

public string AString { get; set; }

public void CopyToClipboard()
{
Rectangle rect = ClientRectangle;
Bitmap b = new Bitmap(rect.Width, rect.Height);
DrawToBitmap(b, rect);

MemoryStream ms = new MemoryStream();
b.Save(ms, Encoder, EncoderParams);
IDataObject dataObject = new DataObject();
//dataObject.SetData("PNG", false, ms);
dataObject.SetData("JPG", false, ms);
Clipboard.Clear();
Clipboard.SetDataObject(dataObject, false);
}

public void Save(string path)
{
Rectangle rect = ClientRectangle;
Bitmap bmp = new Bitmap(rect.Width, rect.Height);
DrawToBitmap(bmp, rect);
bmp.Save(path, Encoder, EncoderParams);
}

private ImageCodecInfo Encoder
{
get { return GetEncoderInfo(Format.Guid); }
}

private ImageFormat Format
{
//get { return System.Drawing.Imaging.ImageFormat.Png; }
get { return System.Drawing.Imaging.ImageFormat.Jpeg; }
}

private ImageCodecInfo GetEncoderInfo(Guid g)
{
ImageCodecInfo[] encoders = ImageCodecInfo.GetImageEncoders();
for (int t = 0; t < encoders.Length; t++)
{
if (encoders[t].FormatID == g)
return encoders[t];
}
return null;
}

private EncoderParameters EncoderParams
{
get { return null; }
}
}
}

--
Thank you,

Christopher Ireland
http://shunyata-kharg.doesntexist.com

"So little time, so little to do."
Oscar Levant

Re: Bitmap + Clipboard + Transparency = Blue Background? Michael Phillips, Jr.
4/16/2008 9:18:00 AM
[quoted text, click to view]

That pretty much covers it. You can try the MSDN documentation to get the
official supported pixel formats.

[quoted text, click to view]

The clipboard viewer utility is old. It was never updated to support the
viewing of newer clipboard formats. That is why you see grayed out
clipboard formats. Nevertheless, the grayed out formats show you what is
supported by the application.

If you check MSDN, you can write your own clipboard viewer that will support
the formats that you need for testing purposes.

[quoted text, click to view]

If I understand you correctly, the above operation is a drag and drop of a
image file not a copy and paste of an image.

There are plenty of code examples on MSDN in c# for drag and drop support.

[quoted text, click to view]

This is a known bug. The enhanced metafile is not a packed format that can
be passed by a MemoryStream backed by global memory. You need to pass a
HENHMETAFILE handle using the CF_ENHMETAFILE clipboard format. You can use
Metafile.GetHenhmetafile(). Pass the handle with P-Invoke SetClipboardData.

Re: Bitmap + Clipboard + Transparency = Blue Background? Christopher Ireland
4/16/2008 11:21:47 AM
Michael,

Thank you again for your help, Michael. I really feel I'm making progress in
this area thanks to you.

[quoted text, click to view]

I don't suppose you have a list (or a link) to the image formats for which
gdiplus allows alpha channels? From the tests I've made here on the image
formats I'm interested in, PNG, EMF and TIFF save with alpha channels in
tact whereas GIF and JPG do not.

[quoted text, click to view]

Yes, that's pretty straightforward to do.

[quoted text, click to view]

We are talking about pasting images into documents here, where both the
operating system and the documents are written by the same software company.
I won't labour the point any more than that :-)

[quoted text, click to view]

Ok, I insert one of the correctly formed transparent PNG images from my
tests into a Word2003 document. The transparency is preserved correctly
within the Word2003 document. I select the image and copy it. The "View"
menu within ClipBook Viewer shows me a long list that includes the "PNG"
format but only the "Enhanced Metafile, Picture, DIB Bitmap and Bitmap"
formats are written in black text. All the other formats, including the
"PNG" format, are written in grey text. I've had a look in the ClipBook
Viewer help file looking for an explanation of these greyed out formats, but
can't find one. Do you have any idea?

I also don't understand why I can copy a transparent PNG, EMF or TIFF file
by selecting it in Windows Explorer and then using Ctrl+C and have it
successfully paste into a Word2003 document with its transparency preserved
but when I use c# to do the same it doesn't work. When I look in ClipBook
Viewer having copied a file from Windows Explorer it tells me that the
format is "Drag-Drop Data", but using DataFormats.FileDrop when I set the
data to the clipboard in c# doesn't work in the same way.

Another difficulty I am experiencing is being able to copy EMF files to the
clipboard at all using c#. I include a full code example below. In the code
below, GetDataPresent returns true but the MemoryStream strm is always
false. I know I am being very demanding on your time and patience, but if
you could take a quick look at the code I would be very grateful.

namespace WindowsFormsApplication1
{
public partial class Form3 : Form
{
public Form3()
{
InitializeComponent();
this.BackColor = Color.Yellow;
InitializeControl();
}

private void InitializeControl()
{
myControl1 = new MyControl();
myControl1.Location = new System.Drawing.Point(40, 12);
myControl1.Size = new System.Drawing.Size(600, 400);
Controls.Add(myControl1);

myControl1.BackColor = Color.Transparent;
myControl1.AString = "My Control";

myControl1.CopyToClipboard();
myControl1.Save(@"C:\temp\mycontrol.emf");

System.Windows.Forms.IDataObject iData = Clipboard.GetDataObject();
if (null != iData)
{
if (iData.GetDataPresent(DataFormats.EnhancedMetafile, false))
{
MemoryStream strm =
(MemoryStream)iData.GetData(DataFormats.EnhancedMetafile);
if (null != strm)
{
Image image = (Bitmap)Image.FromStream(strm, true);
image.Save(@"c:\temp\mycontrol_pasted.emf", ImageFormat.Emf);
}
}
}
}
private MyControl myControl1;
}

public class MyControl : Control
{
public MyControl()
: base()
{
SetStyle(ControlStyles.OptimizedDoubleBuffer, false);
SetStyle(ControlStyles.SupportsTransparentBackColor, true);
}

protected override void OnPaint(PaintEventArgs e)
{
Draw(e.Graphics);
}

public void Draw(Graphics g)
{
Rectangle rect = ClientRectangle;
rect.Inflate(-1, -1);
g.DrawString(AString, new Font("Verdana", 12), Brushes.Black, new
PointF(10, 10));
g.DrawRectangle(Pens.Red, rect);
}

public Metafile Metafile(Graphics gRef, Stream stream)
{
IntPtr hDC = gRef.GetHdc();
Metafile mf = new System.Drawing.Imaging.Metafile(stream, hDC);
gRef.ReleaseHdc(hDC);
gRef.Dispose();

gRef = Graphics.FromImage(mf);
try
{
Draw(gRef);
}
finally
{
gRef.Dispose();
}

return mf;
}

public string AString { get; set; }

public void CopyToClipboard()
{
MemoryStream ms = new MemoryStream();
Save(ms);

IDataObject dataObject = new DataObject();
dataObject.SetData(DataFormats.EnhancedMetafile, false, ms);
Clipboard.Clear();
Clipboard.SetDataObject(dataObject, false);
}

public void Save(string path)
{
FileStream fs = File.Create(path);
Save(fs);
}

public void Save(Stream stream)
{
Bitmap bitmap = new Bitmap(1, 1, PixelFormat.Format24bppRgb);
Graphics gRef = Graphics.FromImage(bitmap);
Metafile meta = Metafile(gRef, stream);
stream.Flush();
stream.Close();
}

private ImageCodecInfo Encoder
{
get { return GetEncoderInfo(Format.Guid); }
}

private ImageFormat Format
{
get { return System.Drawing.Imaging.ImageFormat.Emf; }
}

private ImageCodecInfo GetEncoderInfo(Guid g)
{
ImageCodecInfo[] encoders = ImageCodecInfo.GetImageEncoders();
for (int t = 0; t < encoders.Length; t++)
{
if (encoders[t].FormatID == g)
return encoders[t];
}
return null;
}

private EncoderParameters EncoderParams
{
get { return null; }
}
}
}

--
Thank you,

Christopher Ireland
http://shunyata-kharg.doesntexist.com

"The ultimate authority must always rest with the individual's own reason
and critical analysis."
Dalai Lama

Re: Bitmap + Clipboard + Transparency = Blue Background? Michael Phillips, Jr.
4/17/2008 9:22:38 AM
[quoted text, click to view]