【问题标题】:How can I find reason of the error when SetDIBitsToDevice returns error code (0)当 SetDIBitsToDevice 返回错误代码 (0) 时如何找到错误原因
【发布时间】:2011-12-22 03:09:49
【问题描述】:

背景:我在我的 MFC 应用程序中使用 OpenCV2 库并使用 SetDIBitsToDevice 来显示每个图像。我的问题是以下代码适用于 90% 的图像文件,但不适用于某些旋转图像,原因我不知道。 Whole description of the issue is here

所以我需要找出函数返回图像的 0 错误代码的原因以及我从函数中得到的错误。

根据MSDN

如果设置了零扫描线(例如当 dwHeight 为 0 时)或 函数失败,函数返回零。

那么如果函数返回零,我怎样才能找到错误的细节呢?

更新:我尝试使用 GetLastError() 如下。但实际上消息是“操作成功完成”,这当然不是真的。我将不胜感激任何提示或建议来解决这个问题。

BITMAPINFO* bmi = (BITMAPINFO* )buffer; 
FillBitmapInfo(bmi,width,height,Bpp(pDoc->m_cvImage),0);
int result = SetDIBitsToDevice(pDC->GetSafeHdc(), 100, 100, width,
    height, 0, 0, 0, height, pDoc->m_cvImage.data, bmi,
    DIB_RGB_COLORS);
if(result==0) {
    DWORD error = GetLastError();
    LPVOID lpMsgBuf;
    FormatMessage( 
        FORMAT_MESSAGE_ALLOCATE_BUFFER | 
        FORMAT_MESSAGE_FROM_SYSTEM | 
        FORMAT_MESSAGE_IGNORE_INSERTS,
        NULL,
        error,
        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
        (LPTSTR) &lpMsgBuf,
        0,
        NULL 
    );
    CString text;
    // Process any inserts in lpMsgBuf.
    text= (LPCTSTR)lpMsgBuf;
    // Free the buffer.
    LocalFree( lpMsgBuf );      
    int nResult = AfxMessageBox(text, MB_OK);

}

【问题讨论】:

  • @HansPassant 谢谢。有趣的是,当我使用 FormatMessage 将函数中的值转换为字符串消息时,我得到“操作成功完成”,这是不正确的。
  • 一个常见的错误是调用其他一些获取错误代码重置的winapi函数。立即调用它并将返回值存储在局部变量中。
  • @HansPassant 我不认为我正在这样做。根据google搜索,我认为是Bitmap函数的无描述问题。

标签: c++ windows


【解决方案1】:

如果您打算在 API 失败时调用 GetLastError,则会记录在案。由于文档没有提及 GetLastError,因此似乎在发生故障时除了返回值中编码的信息之外没有提供进一步的信息。

如果函数成功,返回值是个数 扫描线设置。

如果设置了零扫描线(例如当 dwHeight 为 0 时)或函数失败,则函数返回零。

如果驱动程序不支持传递给 SetDIBitsToDevice 的 JPEG 或 PNG 文件图像,该函数将失败并返回 GDI_ERROR。如果确实发生故障,应用程序必须依靠自己的 JPEG 或 PNG 支持将图像解压缩为位图,然后将位图传递给 SetDIBitsToDevice。

恐怕你在这里几乎是一个人。

【讨论】:

  • 是的,它看起来是这样的。你能提出任何解决这个问题的方法吗?
  • 我想我会通过搜索有关失败图像的共同点来解决这个问题
  • 我的 MSDN 库副本说确实如此。我们之前讨论过,不知道发生了什么。
  • @hans 我看过这里:msdn.microsoft.com/en-us/library/dd162974(v=vs.85).aspx 你在哪里看的?
  • 在我自己的副本中,在我安装VS时安装在我的机器上。我不太喜欢网络界面,太慢了。当然是过时了。
【解决方案2】:

大多数 GDI 函数不使用 GetLastError()(有些使用,例如 BitBlt()),并且 GDI 不定义自己的错误代码,而不是 0GDI_ERROR。如果发生故障,通常无法确定实际错误是什么。你只需要仔细检查你的代码,寻找逻辑错误。

由于您遇到旋转图像的问题,我会先查看它们。它们的尺寸可能与您期望的不同,因此它们与您传递给 SetDIBitsToDevice() 的参数不匹配。

【讨论】:

  • 当我将图像设置为灰度时,它以一种奇怪的方式显示。我怀疑行和列弄乱了,但即使我交换了宽度和高度,它也根本不显示原始图像。如果您有兴趣,这里是full description of the issue
猜你喜欢
  • 1970-01-01
  • 2014-06-08
  • 2011-06-12
  • 2019-03-20
  • 1970-01-01
  • 2021-09-02
  • 2019-01-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多