我刚开始使用win32 GDI编程并且很难找到好的参考资料。我有一个简单的应用程序,通过执行以下操作捕获屏幕:
UINT32 x,y;
x = GetSystemMetrics(SM_CXSCREEN);
y = GetSystemMetrics(SM_CYSCREEN);
HDC hdc = GetDC(NULL);
HDC hdcScreen = CreateCompatibleDC(hdc);
HBITMAP hbmp = CreateCompatibleBitmap(hdc, x, y);
SelectObject(hdcScreen, hbmp);
BitBlt(hdcScreen, 0, 0, x, y, hdc, 0, 0, SRCCOPY)
ReleaseDC(NULL, hdc);
UINT32 x,y;
x = GetSystemMetrics(SM_CXSCREEN);
y = GetSystemMetrics(SM_CYSCREEN);
HDC hdc = GetDC(NULL);
HDC hdcScreen = CreateCompatibleDC(hdc);
HBITMAP hbmp = CreateCompatibleBitmap(hdc, x, y);
SelectObject(hdcScreen, hbmp);
BitBlt(hdcScreen, 0, 0, x, y, hdc, 0, 0, SRCCOPY)
ReleaseDC(NULL, hdc);
我正在捕获一个在我的机器上是32位的兼容位图。使用相同/类似的调用如何以8位捕获屏幕?那么16位呢?
答案 0 :(得分:2)
使用CreateDIBSection创建一个8bpp的位图,然后使用BitBlt。
填写BITMAPINFO结构将会很有趣。您不能使用普通的BITMAPINFO结构,因为它只为单个调色板条目分配空间,并且使用8bpp图像 - 您将需要完整的256个条目。
如果你想作弊,可以使用匿名联合声明一个BITMAPINFO,它的调色板有足够的空间。
union
{
BITMAPINFO bmi;
struct {
BITMAPINFOHEADER bmih;
RGBQUAD extra[256];
} dummy;
};
bmi.bmiHeader.biSize = sizeof (bmi.bmiHeader);
bmi.biBitCount = 8;
// and so on.
关于在颜色表中初始化的值...我想不出一种简单的方法来从GDI获得默认的8bpp调色板,而不是8bpp模式。我怀疑CreateHalftonePalette在非调色板设备上不会做任何事情。
答案 1 :(得分:1)
我很确定你必须捕获一个32位的位图,然后自己将其转换为8位。 8位转换通常会丢失相当数量的数据,并且有很多不同的算法可供选择。除非你真的没有没有选择,否则我会重新考虑这样做。这是很长时间,因为大多数人都有很多理由搞乱8位位图 - 而且他们 一团糟。
8位位图(至少是典型的位图)具有“调色板”,其指定要在位图文件中使用的每种(最多)256种颜色的24位值。通常,您希望选择与原始位图中的颜色最接近的颜色。已经发明了 lot 算法来实现这一目标。谷歌搜索“颜色减少算法”之类的东西应该产生相当多的点击,有很多变化,如何做到这一点,折衷执行速度,内存使用等等。我甚至不能开始猜测谁最适合为了你的特殊目的。
正如我前面所说,我的第一个倾向是花些时间和精力来简单地消除这个要求。从32减少到24或甚至16位非常简单,并保留了原始质量的 lot 。转到8位是非常困难的和会失去很多质量。