Note: This question is about pasting from the clipboard, not copying to the clipboard. There are several posts about copying to the clipboard, but couldn't find one that addresses this question.
How can I paste an image with transparency, for example this one, into a winforms app and retain transparency?
I have tried using System.Windows.Forms.GetImage()
, but that produces a bitmap with a black background.
I am copying this image from Google Chrome, which supports several clipboard formats, including DeviceIndependentBitmap
and Format17
.
png , the Shift + Ctrl + F12 key combination is sent to Photoshop, which I have mapped to a Photoshop Action to place the clip. png file into the currently open document. If the utility did not save the image, the standard Ctrl + V key combo is sent to Photoshop and a standard paste is performed.
With the image selected, click on the down arrow present below the Select option. Choose Transparent selection. Voila!
Chrome copies the image to the clipboard in a 24bpp format. Which turns the transparency into black. You can get a 32bpp format out of the clipboard but that requires handling the DIB format. There's no built-in support for that in System.Drawing, you need a little helper function that make the conversion:
private Image GetImageFromClipboard() {
if (Clipboard.GetDataObject() == null) return null;
if (Clipboard.GetDataObject().GetDataPresent(DataFormats.Dib)) {
var dib = ((System.IO.MemoryStream)Clipboard.GetData(DataFormats.Dib)).ToArray();
var width = BitConverter.ToInt32(dib, 4);
var height = BitConverter.ToInt32(dib, 8);
var bpp = BitConverter.ToInt16(dib, 14);
if (bpp == 32) {
var gch = GCHandle.Alloc(dib, GCHandleType.Pinned);
Bitmap bmp = null;
try {
var ptr = new IntPtr((long)gch.AddrOfPinnedObject() + 40);
bmp = new Bitmap(width, height, width * 4, System.Drawing.Imaging.PixelFormat.Format32bppArgb, ptr);
return new Bitmap(bmp);
}
finally {
gch.Free();
if (bmp != null) bmp.Dispose();
}
}
}
return Clipboard.ContainsImage() ? Clipboard.GetImage() : null;
}
Sample usage:
protected override void OnPaint(PaintEventArgs e) {
using (var bmp = GetImageFromClipboard()) {
if (bmp != null) e.Graphics.DrawImage(bmp, 0, 0);
}
}
Which produced this screen-shot with the form's BackgroundImage property set to a stock bitmap:
(I can't comment answers)
Answer of Hans Passant is good, but not correct.
Screenshot saved with this code.
You need to replace var ptr = new IntPtr((long)gch.AddrOfPinnedObject() + 40);
with var ptr = new IntPtr((long)gch.AddrOfPinnedObject() + 52);
Screenshot saved with correct code.
Also you need flip image vertically
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