Как вставить прозрачное изображение из буфера обмена в приложение c# winforms?

Примечание: этот вопрос касается вставки из буфера обмена, а не копирования в буфер обмена. Есть несколько сообщений о копировании в буфер обмена, но не удалось найти тот, который затрагивает этот вопрос.

как я могу вставить изображение с прозрачностью, например в приложение WinForms и сохранить прозрачность?

Я пробовал использовать System.Windows.Forms.GetImage(), но это создает растровое изображение с черным фоном.

я копирую это изображение из В Google Chrome, который поддерживает несколько форматов буфера обмена, в том числе DeviceIndependentBitmap и Format17.

1 ответов


Chrome копирует изображение в буфер обмена в формате 24bpp. Что превращает прозрачность в черноту. Вы можете получить формат 32bpp из буфера обмена, но для этого требуется обработка формата DIB. Для этого в системе нет встроенной поддержки.Рисование, вам нужна небольшая вспомогательная функция, которая делает преобразование:

    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;
    }

пример использования:

    protected override void OnPaint(PaintEventArgs e) {
        using (var bmp = GetImageFromClipboard()) {
            if (bmp != null) e.Graphics.DrawImage(bmp, 0, 0);
        }
    }

который произвел этот снимок экрана со свойством BackgroundImage формы, установленным на запас растровые:

enter image description here