winapi:从 HDC 到 HBITMAP
winapi: from HDC to an HBITMAP
我想做一些我认为相当简单的事情,但是由于我是 winapi 的新手,所以我发现了很多问题。基本上我有一个 HDC(我从加载的位图中进行 BitBlitting),我正在它上面画一个矩形。然后我想将 HDC 的 BitBlt 放到一个新的 HBITMAP 对象上,但可惜现在无济于事。
这是我已经尝试了几个小时的代码
BITMAPINFO info;
Bitmap *tempbmp = Bitmap::FromFile(L"C:\Users\abelajc\Pictures\BackgroundImage.png", false);
HBITMAP loadedbackground;
tempbmp->GetHBITMAP(NULL, &loadedbackground);
HBRUSH hRed = CreateSolidBrush(RGB(255, 0, 0));
HDC pDC = GetDC(0);
HDC TmpDC = CreateCompatibleDC(pDC); //main DC on which we will paint on
HDC dcBmp = CreateCompatibleDC(TmpDC); //DC for the loadedbackground HBitmap
HGDIOBJ TmpObj2 = SelectObject(dcBmp , tempbmp); //Selecting Bitmap in DC
BitBlt(TmpDC, 0, 0, 512, 512, dcBmp, 0, 0, SRCCOPY);
SelectObject(dcBmp, TmpObj2); //Deselecting Bitmap from DC
DeleteDC(dcBmp);
RECT rectangle;
SetRect(&rectangle, 5, 5, 20, 20);
FillRect(TmpDC, &rectangle, hRed);
HDC hCompDC = CreateCompatibleDC(TmpDC);
HBITMAP hBmp = CreateCompatibleBitmap(TmpDC, 512, 512);
HBITMAP hOld = (HBITMAP)SelectObject(hCompDC, hBmp);
BitBlt(hCompDC, 0, 0, 512, 512, TmpDC, 0, 0, SRCCOPY);
SelectObject(hCompDC, hOld);
DeleteDC(hCompDC);
Bitmap *image = new Bitmap(hBmp, NULL);
我认为您只需要对 GDI 做一些说明。
DC 顾名思义:设备上下文。这只是一个上下文,没有什么具体的。一些 DC 是真实图形设备的上下文,其他一些(内存 DC)是内存中虚拟图形表面的上下文。您使用 CreateCompatibleDC
创建的 DC 是内存 DC,但创建 DC 只会创建上下文,而不是内存表面。正如 MSDN 文档所说:
Before an application can use a memory DC for drawing operations, it must select a bitmap of the correct width and height into the DC.
您需要将 HBITMAP 与 DC 相关联。这样做之后,您可以认为绘制到 DC 本质上是绘制到位图。内存DC是位图的'window'。
一旦你明白了这一点,你就会发现你的程序可以大大缩短。如果您还有问题,请随时发表评论。
我想做一些我认为相当简单的事情,但是由于我是 winapi 的新手,所以我发现了很多问题。基本上我有一个 HDC(我从加载的位图中进行 BitBlitting),我正在它上面画一个矩形。然后我想将 HDC 的 BitBlt 放到一个新的 HBITMAP 对象上,但可惜现在无济于事。
这是我已经尝试了几个小时的代码
BITMAPINFO info;
Bitmap *tempbmp = Bitmap::FromFile(L"C:\Users\abelajc\Pictures\BackgroundImage.png", false);
HBITMAP loadedbackground;
tempbmp->GetHBITMAP(NULL, &loadedbackground);
HBRUSH hRed = CreateSolidBrush(RGB(255, 0, 0));
HDC pDC = GetDC(0);
HDC TmpDC = CreateCompatibleDC(pDC); //main DC on which we will paint on
HDC dcBmp = CreateCompatibleDC(TmpDC); //DC for the loadedbackground HBitmap
HGDIOBJ TmpObj2 = SelectObject(dcBmp , tempbmp); //Selecting Bitmap in DC
BitBlt(TmpDC, 0, 0, 512, 512, dcBmp, 0, 0, SRCCOPY);
SelectObject(dcBmp, TmpObj2); //Deselecting Bitmap from DC
DeleteDC(dcBmp);
RECT rectangle;
SetRect(&rectangle, 5, 5, 20, 20);
FillRect(TmpDC, &rectangle, hRed);
HDC hCompDC = CreateCompatibleDC(TmpDC);
HBITMAP hBmp = CreateCompatibleBitmap(TmpDC, 512, 512);
HBITMAP hOld = (HBITMAP)SelectObject(hCompDC, hBmp);
BitBlt(hCompDC, 0, 0, 512, 512, TmpDC, 0, 0, SRCCOPY);
SelectObject(hCompDC, hOld);
DeleteDC(hCompDC);
Bitmap *image = new Bitmap(hBmp, NULL);
我认为您只需要对 GDI 做一些说明。
DC 顾名思义:设备上下文。这只是一个上下文,没有什么具体的。一些 DC 是真实图形设备的上下文,其他一些(内存 DC)是内存中虚拟图形表面的上下文。您使用 CreateCompatibleDC
创建的 DC 是内存 DC,但创建 DC 只会创建上下文,而不是内存表面。正如 MSDN 文档所说:
Before an application can use a memory DC for drawing operations, it must select a bitmap of the correct width and height into the DC.
您需要将 HBITMAP 与 DC 相关联。这样做之后,您可以认为绘制到 DC 本质上是绘制到位图。内存DC是位图的'window'。
一旦你明白了这一点,你就会发现你的程序可以大大缩短。如果您还有问题,请随时发表评论。