将DIB转换为DDB?
作者:互联网
我正在开发一个剪贴板管理器(可以在这里看到:http://flamefusion.net/software/shapeshifter).
但是,我目前遇到的位图(bmp)问题无法真正将自身正确插入剪贴板.我的第一种方法是使用SetClipboardData.
var hBitmap = bmp.GetHBitmap();
SetClipboardData(CF_BITMAP, hBitmap);
我知道其中可能存在内存泄漏,它只是作为测试而进行的.测试失败.粘贴到剪贴板时,Paint无法读取放入剪贴板的图像.
因此,经过大量研究和失败尝试,我得到了一个新理论.我正在使用的位图是从MemoryStream创建的,它是通过先前对Bitmap.Save(Stream,ImageFormat)方法的调用而创建的.这使我相信System.Drawing.Bitmap的GetHBitmap不是SetClipboardData函数期望的HBITMAP.
因此,我尝试了以下方法,并取得了一些成功.
var memDC = CreateCompatibleDC(IntPtr.Zero);
var memBitmap = CreateCompatibleBitmap(memDC, bmp.Width, bmp.Height);
SetClipboardData(CF_BITMAP, memBitmap);
现在,图像以正确的尺寸插入,但为黑色图像.这是很明显的,因为bmp的宽度和高度实际上都不用于创建“兼容”位图.
我假设我必须以某种方式使用BitBlt将我的原始位图复制到此“兼容”位图上,但是我不知道从哪里开始.
你们中的任何GDI向导都知道吗?这里显然需要魔术.
编辑1
就像dthorpe很好地指出的那样,似乎我的问题是我尝试保存的图像实际上是DIB.现在问题已经改变.我需要弄清楚如何从DIB转换为DDB.我知道在执行此操作时会发生alpha损失,但是仍然需要这样做.
编辑2
使用Clipboard.SetImage是不可接受的.这在我的情况下不起作用.我需要使用API.
解决方法:
CF_BITMAP可能是与位图一起使用的错误格式. CF_BITMAP剪贴板格式指定了设备位图,但是今天几乎所有的位图都是DIB-与设备无关的位图.设备位图是相对于系统/硬件设备选项板(请考虑使用EGA图形)的,并且必须与当前显示模式的像素格式匹配. DIB带有自己的颜色信息,其像素格式与显示模式无关.
医生说,如果应用程序从剪贴板读取数据时要求CF_DIB,剪贴板管理器会将CF_BITMAP转换为CF_DIB,但前提是原始图像实际上是当前显示模式像素格式的设备位图.如果不是,则转换将产生垃圾,因为输入是垃圾.
使用CF_DIB而不是CF_BITMAP再试一次.
标签:gdi,clipboard,gdi-2,c,pinvoke 来源: https://codeday.me/bug/20191031/1979647.html