1

I am pasting an image (PNG with transparency) from clipboard:

Dim oDataObj As IDataObject = System.Windows.Forms.Clipboard.GetDataObject()
Dim oImgObj As Image = oDataObj.GetData(DataFormats.Bitmap, True)
oImgObj.Save(temp_local, System.Drawing.Imaging.ImageFormat.Png)

or in C#

IDataObject oDataObj = System.Windows.Forms.Clipboard.GetDataObject();
Image oImgObj = oDataObj.GetData(DataFormats.Bitmap, true);
oImgObj.Save(temp_local, System.Drawing.Imaging.ImageFormat.Png);

The problem is the transparency of image is being lost.

Is there any way to keep image transparency?

Nizam
  • 4,569
  • 3
  • 43
  • 60
  • This is determined largely by the system that put the object _on_ the clipboard... if they add PNG and/or DIB formats, then yes, you can have transparency. Though the DIB one is notoriously unreliable. – Nyerguds Jan 05 '18 at 14:37

3 Answers3

1

Bitmap objects cannot maintain transparency which is why you are losing the transparency

Josh
  • 123
  • 21
1

That is unfortunately how the clip board works, it copies without transparency.

box86rowh
  • 3,415
  • 2
  • 26
  • 37
  • Is there at least any way to convert the transparency to a specific color? If so, I could use the method `MakeTransparent` of a bitmap to achieve what I want. – Nizam Jul 11 '14 at 22:02
  • that's not true, paste your image in paint or paint.net, the transparency is kept – cyrianox Apr 27 '17 at 12:04
1

I found a brilliant solution from here. I have converted the code to VB.NET to adequate to my question. The following code does the trick:

Private Function GetImageFromClipboard() As Image
    If Clipboard.GetDataObject() Is Nothing Then
        Return Nothing
    End If
    If Clipboard.GetDataObject().GetDataPresent(DataFormats.Dib) Then
        Dim dib = DirectCast(Clipboard.GetData(DataFormats.Dib), System.IO.MemoryStream).ToArray()
        Dim width = BitConverter.ToInt32(dib, 4)
        Dim height = BitConverter.ToInt32(dib, 8)
        Dim bpp = BitConverter.ToInt16(dib, 14)
        If bpp = 32 Then
            Dim gch = GCHandle.Alloc(dib, GCHandleType.Pinned)
            Dim bmp As Bitmap = Nothing
            Try
                Dim ptr = New IntPtr(CLng(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 IsNot Nothing Then
                    bmp.Dispose()
                End If
            End Try
        End If
    End If
    Return If(Clipboard.ContainsImage(), Clipboard.GetImage(), Nothing)
End Function
Community
  • 1
  • 1
Nizam
  • 4,569
  • 3
  • 43
  • 60
  • interesting, but it covers only the single 32bpp case. – Nyerguds Sep 17 '17 at 17:34
  • This also seems to be missing many small details, like the fact the image starts 12 bytes later if the DIB header's "compression" is set to 3. Not to mention it technically defines the colour reading of the 32 bits... – Nyerguds Sep 18 '17 at 11:11