首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将DIB转换为DDB?

将DIB转换为DDB?
EN

Stack Overflow用户
提问于 2012-08-28 15:32:37
回答 2查看 1.5K关注 0票数 3

我正在开发一个剪贴板管理器(可以在这里看到:http://flamefusion.net/software/shapeshifter)。

但是,我目前遇到了位图(bmp)的问题,该位图不能正确地插入剪贴板。我的第一个方法是使用SetClipboardData,如下所示。

代码语言:javascript
复制
var hBitmap = bmp.GetHBitmap();
SetClipboardData(CF_BITMAP, hBitmap);

我知道其中潜在的内存泄漏,这完全是作为一种测试。测试失败了。放入剪贴板中的图像在粘贴到剪贴板上时无法被油漆读取。

所以经过大量的研究和失败的尝试,我得到了一个新的理论。我使用的位图是从一个MemoryStream创建的,它是通过以前对Bitmap.Save(Stream, ImageFormat)方法的调用创建的。这让我相信,System.Drawing.BitmapGetHBitmap并不是SetClipboardData函数所期望的那种HBITMAP

因此,我尝试了以下几种方法,取得了一定的成功。

代码语言:javascript
复制
var memDC = CreateCompatibleDC(IntPtr.Zero);
var memBitmap = CreateCompatibleBitmap(memDC, bmp.Width, bmp.Height);
SetClipboardData(CF_BITMAP, memBitmap);

现在,图像插入正确的尺寸,但作为一个黑色的图像。这是非常明显的,因为除了宽度和高度之外,实际上没有任何来自bmp的“兼容”位图用于创建“兼容”位图。

我想我必须以某种方式使用BitBlt将原来的位图复制到现在“兼容”的位图上,但是我不知道从哪里开始。

你们中有哪个GDI巫师知道吗?这里显然需要魔法。

正如编辑1很好地指出的那样,我的问题似乎是,我试图保存的图像实际上是一个DIB。现在问题已经改变了。我需要弄清楚如何从DIB转换成DDB。我知道在做这件事的同时,阿尔法损失,但它仍然是必要的。

编辑2使用Clipboard.SetImage是不可接受的。这在我的情况下行不通。我需要使用API。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-08-28 16:40:45

CF_BITMAP可能是与位图一起使用的错误格式。CF_BITMAP剪贴板格式指定了一个设备位图,但是现在几乎所有的位图都是DIBs --设备独立的位图。设备位图相对于系统/硬件设备调色板(考虑EGA图形),并且必须与当前显示模式的像素格式相匹配。DIBs携带自己的颜色信息,它们的像素格式与显示模式无关。

Docs说,如果应用程序在从剪贴板读取CF_BITMAP时请求CF_DIB,剪贴板管理器将将CF_DIB转换为CF_DIB,但这假定原始图像实际上是当前显示模式像素格式下的设备位图。如果不是,转换将产生垃圾,因为输入是垃圾。

再次尝试使用CF_DIB而不是CF_BITMAP。

票数 2
EN

Stack Overflow用户

发布于 2012-08-28 19:21:01

我觉得你搞得太复杂了。实际上根本不需要使用p/invoke --框架已经为您处理好了。你可以用一条线来完成这个任务:

代码语言:javascript
复制
Clipboard.SetImage(bmp);
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12162676

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档