【发布时间】:2016-01-15 16:43:42
【问题描述】:
我有一些旧的 C++/MFC 代码使用 GDI 在设备上下文 (CDC) 中创建图像,使用像 Rectangle 这样的函数。然后通过CPaintDC 的析构函数将图像绘制到屏幕上。一切正常。
现在我想将图像存储在 PNG 文件中。为此,我正在使用 Windows 映像组件 (WIC)。我可以通过创建位图框架、将像素存储在缓冲区中并使用WritePixels 将像素复制到其中来在 WIC 中创建图像。然后 WIC 通过Commit 将图像存储为 PNG 文件。这一切也都有效。
问题是,如何将我使用 GDI 创建的图像(位于 CDC 中)传输到 WIC 可识别的位置?我正在寻找比 CDC::GetPixel 循环存储到缓冲区后跟 WritePixels 更有效的方法。
Windows 7、Visual Studio 2015、C++。
更新:我正在尝试获取@Andrew Komiagin 建议的 CImage 方法。我的代码是
CDC memdc;
memdc.CreateCompatibleDC(nullptr);
myControl.RenderToDC(memdc); // this draws the image onto the dc
CBitmap bmp;
BOOL ok=bmp.CreateCompatibleBitmap(&memdc, w, h); // w=h=292 defined elsewhere
CBitmap *pOldBitmap=memdc.SelectObject(&bmp);
ok=memdc.BitBlt(0, 0, w, h, &memdc, 0, 0, SRCCOPY);
CImage tempImageObj;
tempImageObj.Attach((HBITMAP)bmp.Detach());
CString outputFilename("outputImage.png");
HRESULT hr=tempImageObj.Save(outputFilename);
这会生成一个全黑正方形、宽 x 高像素的 PNG 图像文件,而不是我绘制的图像。我知道RenderToDC 正在正确绘制图像(见下文)。
为了比较,这是在MyControl::OnPaint 中的控件(源自CStatic):
CPaintDC dc(this); // device context for painting
RenderToDC(dc); // this draws the image onto the dc
// Painted to screen by CPaintDC's destructor
图像显示正确。
【问题讨论】:
-
您可以从 CDC 创建 HBITMAP,然后使用 IWICImagingFactory::CreateBitmapFromHBITMAP。
-
@Simon Mourier:我最初尝试过这个,但我不知道如何从 CDC 获取位图。使用 HBITMAP 操作符可以获得一个空位图的句柄。显然,CDC 包含绘制的像素,但其附加的位图不包含。能否举例说明如何将像素放入位图中?
-
这里解释stackoverflow.com/questions/351236/copy-hdc-contents-to-bitmap。使用MFC,您可以直接使用CBitmap类而不是GDI,当然这里有一个示例(SaveAsImage):codeproject.com/Articles/253054/…
-
您正在创建单色位图 (
bmp.CreateCompatibleBitmap(&memdc, w, h);)。请参阅CreateCompatibleBitmap:“创建内存设备上下文时,它最初会选择一个 1×1 单色位图。如果在 CreateCompatibleBitmap 中使用此内存设备上下文,则创建的位图是单色位图。"您需要传递带有适当颜色信息的设备上下文。