【问题标题】:Keep image transparency from clipboard image保持剪贴板图像的图像透明度
【发布时间】:2017-04-27 20:13:59
【问题描述】:

我正在从剪贴板粘贴一张图片(透明的 PNG):

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)

或在 C# 中

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

问题是图像的透明度正在丢失。

有什么办法可以保持图片的透明度?

【问题讨论】:

  • 这主要是由将对象放在剪贴板上的系统决定的……如果他们添加了PNG和/或DIB格式,那么是的,你可以有透明度。虽然 DIB 是出了名的不可靠。

标签: c# vb.net vb.net-2010


【解决方案1】:

位图对象无法保持透明度,这就是您失去透明度的原因

【讨论】:

  • 有没有其他方法可以在不使用位图的情况下从剪贴板粘贴图像?
  • 这只是一件接一件的事情...... WTF Microsoft ?!?
【解决方案2】:

不幸的是,剪贴板就是这样工作的,它复制时没有透明度。

【讨论】:

  • 至少有什么方法可以将透明度转换为特定颜色吗?如果是这样,我可以使用位图的方法MakeTransparent来实现我想要的。
  • 那不是真的,把你的图片粘贴到paint或paint.net中,保持透明度
【解决方案3】:

我从here 找到了一个绝妙的解决方案。我已将代码转换为 VB.NET 以解决我的问题。以下代码可以解决问题:

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

【讨论】:

  • 很有趣,但它只涵盖了单个 32bpp 的情况。
  • 这似乎也遗漏了许多小细节,例如如果 DIB 标头的“压缩”设置为 3,图像将在 12 个字节后开始。更不用说它在技术上定义了32 位...
猜你喜欢
  • 1970-01-01
  • 2017-10-25
  • 1970-01-01
  • 1970-01-01
  • 2021-10-08
  • 1970-01-01
  • 1970-01-01
  • 2014-05-21
  • 1970-01-01
相关资源
最近更新 更多