How to paste a transparent image from the clipboard in a C# winforms app?

后端 未结 2 821

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 ad

相关标签:
2条回答
  • 2021-01-12 09:41

    (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

    0 讨论(0)
  • 2021-01-12 10:03

    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:

    enter image description here

    0 讨论(0)
提交回复
热议问题