5

如果给定 HBITMAP 指针,并且我的应用程序是控制台应用程序,如何从 hbitmap 获取图像字节。我尝试使用需要诸如 HDC 之类的参数的 GetDIBits,但我无法获得。

编辑:我从文件加载位图:

HBITMAP bm = 0; 
BITMAP Bitmap;
bm = (HBITMAP)LoadImage (0, TEXT("C:\\img1.bmp"), IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);

我将 HBITMAP 传递给函数并期望得到另一个处理图像的 HBITMAP:

HBITMAP out1 = func(bm);

其中 func 是:

HBITMAP func(HBITMAP im);

问题是如何从 HBITMAP 获取图像字节。

4

5 回答 5

12

最简单的方法是使用GetDIBits(nor GetBitmapBits)。这些功能很糟糕,因为它们复制了数据。
如果您直接想要数据,只需使用(对于 DDB 位图)

BITMAP bitmap;
GetObject(hBitmap, sizeof(bitmap), (LPVoid)&bitmap);

对于 DIB 位图使用

DIBSECTION dib;
GetObject(hBitmap, sizeof(dib), (LPVOID)&dib);

GetObject 信息,请参阅:http:
//msdn.microsoft.com/en-us/library/windows/desktop/dd144904%28v=vs.85%29.aspx

这不会涉及任何数据复制,从而避免了与 GetDIBits 相关的复杂问题,请参阅:http:
//msdn.microsoft.com/en-us/library/windows/desktop/dd144879%28v=vs.85%29。 aspx
埃斯普。底部的评论以解释困难GetDIBits

请注意,您没有获得调色板信息,但由于大多数位图无论如何都是 24 位或 32 位,这在大多数情况下几乎不是问题。

于 2014-10-31T11:49:26.193 回答
1

既然你是LoadImage用来获取的HBITMAP,那么它确实是一个 DIB(与设备无关的位图)(他们称之为 DIB 部分)。但是,您没有颜色信息。

此 MSDN HOWTO向您展示了如何将 DIB 部分选择到内存 DC 中。然后他们继续使用GetDIBColorTable来获取调色板。但是,我相信从那里开始,您可以使用该 DCGetDIBits来获取 RGB 位图信息,就像您尝试做的那样。

这是它的一般要点:

// Create a memory DC and select the DIBSection into it
hMemDC = CreateCompatibleDC( NULL );
(HBITMAP)SelectObject( hMemDC, hBitmap );

GetDIBits(hMemDC, hBitmap, ...);

您会在他们的代码中注意到SelectObject返回DC 中内容的句柄。然后他们在调用之前恢复它DeleteDC。我不确定它是否完全有必要,但他们会这样做。为了清楚起见,我把它留在这里。

于 2013-01-08T05:33:47.443 回答
1

对我们有用的是:GetDIBits在设备上下文中仍然选择正确的调色板(如果是索引颜色)时调用。(如果没有选择调色板,颜色就会出现乱码。)

但在我们的用例中,事实证明 DIB 部分的性能要好得多,所以也要检查它们并进行基准测试。但是,有一些问题。Windows 不会使用调色板,我们必须SetDIBColorTable在使用前调用。但是设备上下文仍然需要一个条目(仅限黑色)虚拟调色板选择并实现到设备上下文中,否则 Windows 也会忽略由SetDIBColorTable. 两者都SetDIBColorTable需要RealizePalette存在,否则颜色会乱码。

于 2017-01-18T13:59:57.580 回答
0

编辑问题后查看新答案...

如果没有设备上下文句柄 ( ),您将无法执行此操作HDC。这是因为GetDIBits期望HBITMAP

位图句柄。这必须是兼容的位图 (DDB)。

DDB 是一个与设备相关的位图,(与 DIB 或与设备无关的位图相反)。这意味着:

请注意,DDB 不包含颜色值;相反,颜色采用与设备相关的格式。

这就是为什么GetDIBits需要一个HDC. 否则无法获取颜色信息。

也许一个很好的问题是,你从哪里得到一个HBITMAP没有陪伴的HDC


如果您尝试在内存中创建此位图,首先您可以调用CreateCompatibleDC创建与某些设备兼容的内存 DC,然后使用该 DC创建兼容位图。然后你有一个HBITMAPHDC你喜欢的工作。否则,如果你不知道你HBITMAP指的是什么,你就不能指望用它做任何有用的事情。

于 2013-01-08T03:14:33.933 回答
0

您甚至可以从控制台尝试 GetBitmapBits API。更多信息:http: //msdn.microsoft.com/en-us/library/windows/desktop/dd144850%28v=vs.85%29.aspx

只需传递 HBITMAP 句柄,你就会得到你的字节

于 2013-01-08T03:18:02.397 回答