8

I'm trying to save a copied image from the clipboard but it's losing its alpha channel:

Image clipboardImage = Clipboard.GetImage();
string imagePath = Path.GetTempFileName();
clipboardImage.Save(imagePath);

If I copy a 32bit image from PhotoShop or IE/Firefox/Chrome and run the above code, the output loses its alpha channel, instead it is saved against a black background.

The image is saved as PNG, which can contain an alpha channel.

The correct data appears to be in the clipboard because pasting into other applications (such as PhotoShop) retains the alpha channel.

Can anyone put me out of my misery?

Thanks in advance!

Update:

// outputs FALSE
Debug.WriteLine(Image.IsAlphaPixelFormat(Clipboard.GetImage().PixelFormat));

The above suggests that the alpha data is lost as soon as it's taken out of the clipboard. Perhaps I need to get it out of the clipboard some other way?

JaffaTheCake
  • 13,895
  • 4
  • 51
  • 54

4 Answers4

8

Instead of calling Clipboard.GetImage(), try calling Clipboard.GetDataObject()

This returns an IDataObject, which you can in turn query by calling dataObject.GetFormats(). GetFormats() returns the type formats supported by the Clipboard object - there may be a more precise format supported that you can use to extract the data.

Kevin Pullin
  • 13,122
  • 3
  • 24
  • 33
  • 3
    This is the most likely solution. The generic image format on the clipboard has 2 decades of backwards compatiblity to contend with. It's almost certain that Windows deliberately converts any 32bit image down to 24bit when it's requested in CFBITMAP format. – David Jun 15 '09 at 22:53
  • 1
    I haven't touched the clipboard in a long time, but checking MSDN it looks like the specific format you want to check for CF_DIBV5, which is the format for images with extended color information (alpha channel, more then 8bits per color, etc) – David Jun 15 '09 at 22:59
  • Looks like the problem is much more complicated than I thought, and I was mistaken when I said I could copy images from browsers to PhotoShop and retain transparency. I can copy within PhotoShop, but I guess it's just storing a reference to the layer on the clipboard, rather than the image data. "Adobe Photoshop Image" is one of the formats returned by GetFormats, but I simply get null when I try and read this data. Many thanks for all the help! – JaffaTheCake Jun 16 '09 at 08:19
  • 1
    About Photoshop's clipboard hell, read my post in here: http://stackoverflow.com/questions/12258519/how-to-save-pngimage-from-clipboard/18006360#18006360 - I use VBS/COM to generate PNG from within photoshop with its clipboard contents, then read the PNG onto my program. – Петър Петров Aug 02 '13 at 07:40
  • This is indeed the solution, but sadly, DIB5 doesn't seem to be commonly used. More often than not, applications (including Windows itself) use 32-bit RGB DIB (not v5; the old v1) and just pretend the 4th byte makes it ARGB. I posted code to try and get an alpha-capable image from the DataObject in various used alpha-capable formats in [this answer](https://stackoverflow.com/a/46424800/395685). – Nyerguds Oct 16 '17 at 11:22
3

It might be like this article suggests, that the Clipboard object, working within Win32, is only able to manage bitmaps, which don't feature the transparent/partially transparent alpha channel. The OLE clipboard is more capable, it seems:

However, the netez was the best article I found on the topic. (beware I haven't tested this myself)

Henrik
  • 9,714
  • 5
  • 53
  • 87
  • I know this is an old answer, and links to even older resources, but as a warning to readers: there's a shocking amount of mis-information here. User32 clipboard is just as capable as OLE and provides a lot of convenience (it's just a wrapper). The key is to request and parse the `CF_DIB` or `CF_DIBV5` clipboard format. You also do not need OLE to be initialized to use this API as stated in the netez article, but if you wish to _write_ data to the clipboard, you must have an open window (and pass it to `OpenClipboard(hwnd)`) before subsequently calling `EmptyClipboard` and `SetClipboardData`. – caesay Mar 07 '21 at 13:43
0

I am just using Forms methode. Its not that nice solution like using GetFormat like Kevin is telling us but its more quick and works quiete well at all.

  'Dim bm As BitmapSource = Clipboard.GetImage()'looses alpha channel
                'Dim bmS As New WriteableBitmap(bm)'does work but still without alpha information
                Dim bmF As System.Drawing.Bitmap = System.Windows.Forms.Clipboard.GetImage 'Get working image
                Dim bmS As BitmapSource = TB.Imaging.WPF.BitmapToWpfBitmapSource(bmF, Me) 'convert Bitmap into BitmapSource
                Me.Source = bmS
Nasenbaer
  • 4,810
  • 11
  • 53
  • 86
0

The image is being saved as a bitmap where the transparent pixels are visible on the clipboard so use this code

Bitmap clipboardImage = Clipboard.GetImage();
clipboardImage.MakeTransparent()
string imagePath = Path.GetTempFileName();
clipboardImage.Save(imagePath);
Jim
  • 601
  • 6
  • 17
  • MakeTransparent will only make a single colour transparent, the alpha information is lost before that line :( – JaffaTheCake Jun 15 '09 at 22:33
  • I know it works properly when i copied an image from firefox to my program, but i see that it didnt copy drop shadows – Jim Jun 15 '09 at 22:38