2

如何将类似位图的结构转换为 HDC?

我现在正在用 c++、gdi 编写图像处理程序。

如果我有HDC。我可以通过以下代码在 gdi 中的 HDC 上绘制我喜欢的任何内容。

// HDC is handy.
HDC dc;
dc.DrawXXX       // I can draw using gdi method.
Graphics gr(dc); // now I can also draw on the dc using gdi+ method.

我的应用程序基于 FreeImage。我制作了 fipImage。(使用像 Bitmap 这样的数据结构)

但是如果我想在fipWinImage上绘图,现在我必须将fipWinImage复制到Bitmap上,然后在Bitmap上绘图,最后再将位图转换为fipImage,这是耗时耗内存的。

将 fipImage 转换为位图 -> 在位图上绘制 -> 将位图转换为 fipWinImage

fipWinImage imagefip;
Bitmap* tempImg = new Bitmap(imagefip->GetWidth(), imagefip.GetHeigt(), PixelFormat24bppRGB); // memory comsuming is image is large
Graphics *pGr = Graphics::FromImage(tempImg);

HDC dc = pGr->GetHDC();

RECT rec;
rec.left = 0;
rec.top = 0;
rec.right = imagefip.GetWidth();
rec.bottom = imagefip.GetHeight();
fipImage.draw(dc, rec); // using stretchdibits()
pGr->ReleaseHDC(dc);

Graphics gr(tempImg);
HDC dc = gr.GetHDC();         // Get an Hdc, draw using gdi method
gr.ReleaseHDC(tempDC);     //
gr.drawXXX                            // Draw using gdi+ method.


fipWinImage fipImg;             // final result fipWinImage.
HBITMAP temp;
Color color;
tempImg->GetHBITMAP(color, &temp);
fipImg->copyFromBitmap(temp);

我想直接从 fipImage 构建一个 HDC。并直接在 fipWinImage 上绘制我该怎么做?

4

2 回答 2

2

首先澄清几点:

设备上下文基本上是一种结构,可以记住诸如前景色和背景色、画笔、字体信息和物理绘图表面(位图)等内容。

这是一件很方便的事情,因此当您一个接一个地进行图形操作时,您不必一直指定所有这些内容。您还可以通过这种方式更轻松地传递所有这些设置。这就是 DC 真正的全部 - 只是一组绘图参数,包括要绘制的表面。

“HDC”只是这些结构之一的句柄(引用)。作为“句柄”,窗口可以在内存中移动结构以管理可用空间,而不会弄乱指向它的指针。

如果您有权访问正在使用的库的源代码,请检查 fipWinImage::draw(...) 方法。如果他们使用 StretchDIBits,那么他们必须在某个时候将原始位图数据转换为兼容格式。fipWinImage 类也有可能包装了底层的 BITMAP 或 DIB 等。

获得自己的 HDC 的最后一步......

位图被“选择”到设备上下文中,并且一次只能选择到单个 DC。如果您可以从 fipWinImage 中获取内部 HBITMAP,则可以将其选入另一个 DC(假设它仍未选入另一个 HC)。

创建 DC 时,Windows 会自动为其创建 1x1 位图(因为 DC 必须始终具有选定的位图)。当您在新位图中选择时,您将获得返回给您的先前选择的位图的句柄。坚持下去,因为完成后您需要将其放回原处。

希望有帮助。

于 2010-02-04T05:35:20.743 回答
0

我不知道 FreeImage,但如果您可以从中获得指向实际像素数据(DIB 部分)的指针,您可以创建一个共享它的 HBITMAP,而不必每次都复制数据。

于 2009-07-23T03:47:22.297 回答