【问题标题】:How can I get an image out of the clipboard without losing the alpha channel in .NET?如何在不丢失 .NET 中的 alpha 通道的情况下从剪贴板中获取图像?
【发布时间】:2010-11-03 04:12:28
【问题描述】:

我正在尝试从剪贴板保存复制的图像,但它丢失了 alpha 通道:

Image clipboardImage = Clipboard.GetImage();
string imagePath = Path.GetTempFileName();
clipboardImage.Save(imagePath);

如果我从 PhotoShop 或 IE/Firefox/Chrome 复制 32 位图像并运行上述代码,输出将丢失其 alpha 通道,而是以黑色背景保存。

图片保存为PNG,可以包含一个alpha通道。

正确的数据似乎在剪贴板中,因为粘贴到其他应用程序(例如 PhotoShop)会保留 Alpha 通道。

谁能让我摆脱痛苦?

提前致谢!

更新:

// outputs FALSE
Debug.WriteLine(Image.IsAlphaPixelFormat(Clipboard.GetImage().PixelFormat));

以上内容表明,alpha 数据一旦从剪贴板中取出就会丢失。也许我需要以其他方式将其从剪贴板中取出?

【问题讨论】:

  • +1 只是为了正确使用它和它的
  • 好问题。如果你已经解决了,也许你想用一个工作代码更新你的问题,好吗?

标签: c# .net image png clipboard


【解决方案1】:

不要调用Clipboard.GetImage(),而是尝试调用Clipboard.GetDataObject()

这将返回一个 IDataObject,您可以通过调用 dataObject.GetFormats() 依次查询它。 GetFormats() 返回剪贴板对象支持的类型格式 - 可能支持更精确的格式,您可以使用它来提取数据。

【讨论】:

  • 这是最可能的解决方案。剪贴板上的通用图像格式具有 2 年的向后兼容性需要应对。几乎可以肯定的是,当以 CFBITMAP 格式请求任何 32 位图像时,Windows 会故意将其转换为 24 位。
  • 好久没碰剪贴板了,但是查了MSDN好像是你要查的具体格式CF_DIBV5,是带有扩展颜色信息的图片格式(alpha通道,每种颜色超过 8 位等)
  • 看起来问题比我想象的要复杂得多,当我说我可以将图像从浏览器复制到 PhotoShop 并保持透明度时我错了。我可以在 PhotoShop 中复制,但我猜它只是在剪贴板上存储对图层的引用,而不是图像数据。 “Adobe Photoshop Image”是 GetFormats 返回的格式之一,但当我尝试读取此数据时,我只是得到空值。非常感谢所有的帮助!
  • 关于 Photoshop 的剪贴板地狱,请在此处阅读我的帖子:stackoverflow.com/questions/12258519/… - 我使用 VBS/COM 从 Photoshop 中生成带有剪贴板内容的 PNG,然后将 PNG 读取到我的程序中。
  • 这确实是解决方案,但遗憾的是,DIB5似乎并不常用。通常情况下,应用程序(包括 Windows 本身)使用 32 位 RGB DIB(不是 v5;旧 v1)并且只是假装第 4 个字节使其成为 ARGB。我在this answer 中发布了代码以尝试从 DataObject 中以各种使用的支持 alpha 的格式获取支持 alpha 的图像。
【解决方案2】:

可能就像this article 建议的那样,在 Win32 中工作的剪贴板对象只能管理不具有透明/部分透明 Alpha 通道的位图。 OLE 剪贴板功能更强大,看来:

但是,netez 是我找到的关于该主题的最佳文章。 (注意我自己没有测试过)

【讨论】:

  • 我知道这是一个旧答案,并且链接到更旧的资源,但作为对读者的警告:这里有大量令人震惊的错误信息。 User32 剪贴板与 OLE 一样强大,并提供了很多便利(它只是一个包装器)。关键是请求和解析CF_DIBCF_DIBV5 剪贴板格式。如 netez 文章中所述,您也不需要初始化 OLE 即可使用此 API,但如果您希望将数据 写入 到剪贴板,则必须有一个打开的窗口(并将其传递给 @ 987654328@),然后调用EmptyClipboardSetClipboardData
【解决方案3】:

图像被保存为位图,透明像素在剪贴板上可见,因此请使用此代码

Bitmap clipboardImage = Clipboard.GetImage();
clipboardImage.MakeTransparent()
string imagePath = Path.GetTempFileName();
clipboardImage.Save(imagePath);

【讨论】:

  • MakeTransparent 只会使单一颜色透明,alpha 信息在该行之前丢失:(
  • 我知道当我将图像从 firefox 复制到我的程序时它可以正常工作,但我发现它没有复制阴影
【解决方案4】:

我只是使用表单方法。它不是像 Kevin 告诉我们的那样使用 GetFormat 那样好的解决方案,但它更快,而且运行起来更安静。

  'Dim bm As BitmapSource = Clipboard.GetImage()'looses alpha channel
                'Dim bmS As New WriteableBitmap(bm)'does work but still without alpha information
                Dim bmF As System.Drawing.Bitmap = System.Windows.Forms.Clipboard.GetImage 'Get working image
                Dim bmS As BitmapSource = TB.Imaging.WPF.BitmapToWpfBitmapSource(bmF, Me) 'convert Bitmap into BitmapSource
                Me.Source = bmS

【讨论】:

    猜你喜欢
    • 2013-03-19
    • 2013-04-17
    • 2012-08-18
    • 2017-10-25
    • 2013-02-21
    • 2012-05-17
    • 2014-08-17
    • 2019-12-07
    • 1970-01-01
    相关资源
    最近更新 更多