【问题标题】:Screen capture only returns a black image屏幕截图仅返回黑色图像
【发布时间】:2015-06-20 12:55:12
【问题描述】:

我正在尝试对我的 MFC 应用程序中的主对话框进行屏幕截图并将其保存为图像文件。我尝试了我可以在网上找到的每个示例,并且总是得到相同的结果:图像文件具有正确的尺寸(我尝试使用除主要对话框之外的对话框来确定),但它都是黑色的。我最近的解决方案是使用 CBitmap 类将主对话框句柄传输到 CImage。这是我的代码:

CWnd* mainWindow;
CDC* mainWindowDC;
CBitmap bitmapToSave;
CImage imageToSave;
CRect windowRect;

//Get main window context and create bitmap from it
mainWindow = AfxGetMainWnd();
mainWindowDC = mainWindow->GetWindowDC();
mainWindow->GetWindowRect(&windowRect);
bitmapToSave.CreateCompatibleBitmap(mainWindowDC, windowRect.Width(), windowRect.Height());
imageToSave.Attach(bitmapToSave);
imageToSave.Save("C:\\Capture\\image.bmp", Gdiplus::ImageFormatBMP);

【问题讨论】:

    标签: c++ image mfc screenshot cbitmap


    【解决方案1】:

    方法如下:

    HRESULT CaptureScreen(const CString& sImageFilePath)
    {
       CWnd* pMainWnd = AfxGetMainWnd();
       CRect rc;
       pMainWnd->GetWindowRect(rc);
       CImage img;
       img.Create(rc.Width(), rc.Height(), 24);
       CDC memdc;
       CDC* pDC = pMainWnd->GetWindowDC();
       memdc.CreateCompatibleDC(pDC);
       CBitmap* pOldBitmap = memdc.SelectObject(CBitmap::FromHandle((HBITMAP)img));
       memdc.BitBlt(0, 0, rc.Width(), rc.Height(), pDC, 0, 0, SRCCOPY);
       memdc.SelectObject(pOldBitmap);
       return img.Save(sImageFilePath, Gdiplus::ImageFormatPNG);
    }
    

    也请看看这个不错的实现:http://www.codeguru.com/cpp/article.php/c18347/C-Programming-Easy-Screen-Capture-Using-MFCATL.htm

    【讨论】:

    • 这是为我返回的白色图像
    • 我刚刚更新了捕获 MFC 应用程序主窗口的代码。现在它按预期工作(在我的机器上测试)。
    • 这似乎奏效了,非常感谢!在这种情况下我应该调用 ReleaseDC 还是 DeleteDC?
    • 是的,您需要致电ReleaseDC() 获取pDC(通过GetWindowDC() 检索)。其余的 DC(在堆栈上创建)将在超出范围时自动销毁(析构函数调用 ReleaseDC())。
    • 所以理想情况就像捕获桌面屏幕但找到想要的窗口矩形(位置和大小)并仅捕获该区域。但只有当该窗口是前景窗口时它才能正常工作。
    【解决方案2】:

    您创建了位图,但没有在其中添加任何内容。你需要从一个 DC 到另一个 DC 复制屏幕上的内容。

    // ...
    CMemDC dcMem;
    dcMem.CreateCompatibleDC(&mainWindowDC);
    CBitmap * pOld = dcMem.SelectObject(&bitmapToSave);
    dcMem.BitBlt(0, 0, windowRect.Width(), windowRect.Height(), &mainWindowDC, windowRect.left, windowRect.top, SRCCOPY);
    dcMem.SelectObject(pOld);
    // ...
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多