如果我给定hbitmap指针,我如何从hbitmap获得图像字节,并且我的应用程序是控制台应用程序。我尝试使用GetDIBits,它需要HDC等参数,但我无法获得。
编辑:我从文件中加载位图:
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获取图像字节
最简单的方法是而不是使用GetDIBits
(也不是GetBitmapBits
)。这些函数很糟糕,因为它们会复制数据。
如果直接需要数据,只需使用(对于DDB位图)
BITMAP bitmap;
GetObject(hBitmap, sizeof(bitmap), (LPVOID)&bitmap);
对于DIB位图使用
DIBSECTION dib;
GetObject(hBitmap, sizeof(dib), (LPVOID)&dib);
GetObject info,参见:
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位,这在大多数情况下几乎不是问题。
既然您使用LoadImage
来获得HBITMAP
,那么它确实是一个DIB(设备独立位图)(他们称之为DIBsection)。但是,您没有颜色信息。
MSDN HOWTO向您展示了如何将DIBsection选择到内存DC中。然后他们继续使用GetDIBColorTable
来获得调色板。然而,我相信从那里,有了那个DC,你可以使用GetDIBits
来获得RGB位图信息,就像你试图做的那样。
大意如下:
// Create a memory DC and select the DIBSection into it
hMemDC = CreateCompatibleDC( NULL );
(HBITMAP)SelectObject( hMemDC, hBitmap );
GetDIBits(hMemDC, hBitmap, ...);
你会注意到在他们的代码中,SelectObject
返回一个句柄在DC中是什么。然后在调用DeleteDC
之前恢复该值。我不确定这是否完全必要,但他们确实这么做了。为了清楚起见,我把它留在这里了。
我们的工作是这样的:调用GetDIBits
,而正确的调色板(如果索引颜色)仍然被选择到设备上下文中。(没有选择调色板,颜色乱码。)
但是在我们的用例中,事实证明DIB部分的性能要好得多,所以也可以检查这些部分并进行基准测试。然而,也有一些陷阱。Windows不会使用调色板,我们必须在使用之前调用SetDIBColorTable
。但是设备上下文仍然需要一个单条目(只有黑色)虚拟调色板,选择并将实现到设备上下文中,否则Windows也会忽略由SetDIBColorTable
设置的调色板。SetDIBColorTable
和RealizePalette
都需要出现,否则颜色会乱码。
查看自问题编辑以来的新答案
如果没有设备上下文的句柄(HDC
),就不能这样做。这是因为GetDIBits
期望HBITMAP
为
位图的句柄。这必须是一个兼容的位图(DDB)。
DDB是设备相关位图(与DIB或设备无关位图相反)。这意味着:
注意,DDB不包含颜色值;相反,颜色是一种与设备相关的格式。
这就是为什么GetDIBits
需要HDC
。否则无法获取颜色信息。
也许一个好问题是,你从哪里得到一个没有附带的HDC
的HBITMAP
?
如果你想在内存中创建这个位图,首先你可以调用CreateCompatibleDC
来创建一个与某些设备兼容的内存DC,然后用那个DC创建ecompatiblebitmap。然后你有一个HBITMAP
和HDC
工作,因为你喜欢。否则,如果你不知道你的HBITMAP
指向什么,你就不能指望用它做任何有用的事情。
您甚至可以从控制台尝试GetBitmapBits API。更多:http://msdn.microsoft.com/en-us/library/windows/desktop/dd144850%28v=vs.85%29.aspx
只要传递HBITMAP句柄,你就会得到你的字节