CreateDIBSection为同一图像返回不一致的位图位值
CreateDIBSection returns inconsistent bitmap bit values for the same image
这是一个关于CreateDIBSection的扩展问题。
我用它来获得使用Direct3D绘制的同一图像的bitMap位值,以验证其Direct3D渲染的一致性,即只要我每次运行程序(绘制同一图像)时都获得相同的bitMap位值,那么我就认为Direct3D渲染通过了。
然而,奇怪的是,我只能在运行程序的前4次(绘制相同图像)中获得相同的bitMap位值(来自下面代码中所示的"图像"),在第5次之后,bitMap位的值的结果将开始略有变化(只有少量字节发生了变化,其余大部分字节仍然不变),并且永远不会得到与前4次相同的bitMap比特值。
但是,一旦我重新启动计算机并再次开始运行我的程序,我就会返回相同的模式:在运行程序的前4次中,我获得的bitMap比特值与第一次尝试完全相同,但接下来的运行将导致不同的bitMap位值。
我能想到的两个可能的原因:
-
GPU的渲染有一些轻微的不一致,这意味着GPU可能包含一些缺陷,但我不是GPU专家,所以我真的没有信心以这种方式得出结论。
-
我知道CreateDIB部分将自行处理内存分配,是否有可能在调用DeleteObject后内存没有正确清理,并影响bitMap位值中的一些位?(在本次讨论中,我遵循了释放内存的步骤,但这对我获得相同图像的一致位图位值没有帮助。)
问题:当我们从同一张图像中获取bitMap时,我们如何每次都能获得一致的bitMap比特值(这可能吗?)?
谢谢。
代码:
#include <Windows.h>
#include <cstdint>
HWND m_hwnd;
void GetBitMapInfo(const int& x_Coordinate, const int& y_Coordinate, const int& iWidth, const int& iHeight)
{
DWORD imageSize = iWidth * iHeight * 4;
// Get the display window
HDC displayWindow = GetDC(m_hwnd);
HDC hdc = CreateCompatibleDC(displayWindow);
// Fill in the Bitmap information
BITMAPINFO bmpInfo;
ZeroMemory(&bmpInfo, sizeof(BITMAPINFO));
bmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmpInfo.bmiHeader.biWidth = iWidth;
bmpInfo.bmiHeader.biHeight = iHeight;
bmpInfo.bmiHeader.biPlanes = 1;
bmpInfo.bmiHeader.biBitCount = 32;
bmpInfo.bmiHeader.biCompression = BI_RGB;
bmpInfo.bmiHeader.biSizeImage = 0;
bmpInfo.bmiHeader.biClrUsed = 0;
bmpInfo.bmiHeader.biClrImportant = 0;
// Create the storage for the pixel information
uint8_t* image = nullptr;
// Populate the storage with the BMP pixel information
HBITMAP hBitmap = CreateDIBSection(hdc, &bmpInfo, DIB_RGB_COLORS, (void**)(&image), nullptr, NULL);
HGDIOBJ save = SelectObject(hdc, hBitmap);
BitBlt(hdc, x_Coordinate, y_Coordinate, iWidth, iHeight, displayWindow, 0, 0, SRCCOPY);
DeleteObject(SelectObject(hdc, save));
DeleteDC(hdc);
DeleteDC(displayWindow);
DeleteObject(hBitmap);
return;
}
int main()
{
GetBitMapInfo(0, 0, 1920, 1080);
return 0;
}
我最终从根本上解决了这个问题,这与CreateDBSection()无关,而是由于旋转角度,我将其传递给DirectX::XMMatrixRotationY以控制3D对象渲染的旋转(在教程的GraphicsClass::Frame()下,链接如下)。
原始代码实际上是这样设置的,即它将无限循环通过3D对象渲染(和旋转),直到用户按下escape键退出,因此它使旋转角度可变为静态。
但我只希望三维对象有一个完整的旋转。由于角度是一个静态变量,所以我修改的程序的逻辑出错,它只进行了一次完整的旋转。因此,静态角度会从上一次运行中累积起来(我在验证过程中多次循环修改后的测试),这导致接下来的重复测试运行的起始旋转角度不同,因为角度不断增加,直到它将自己重置回0度并重新开始。
由于这个小偏移,最终渲染帧将停止在不同的部分。CreateDBSection()返回的位图位值(我将其用于自己的CRC检查目的,以验证3D对象渲染的一致性)基于渲染完成后和窗口被破坏前最后显示的帧,当然会与开始运行时不同,因此会使我的CRC(循环冗余检查)不断变化。
我更正了我的代码,以便每次执行测试时,旋转总是从零度开始,以360度结束,然后退出测试。之后,无论我为测试重复运行了多少个循环,返回的位图位值都是一致的。
摘要:
- CreateDBSection()对返回的位图位值没有问题(我是因为不清楚Direct3D渲染和我糟糕的C++而遇到问题的人,我会改进自己;)
- 我已经尝试过图形驱动程序更新(通过"英特尔驱动程序与支持助手"检查驱动程序状态,尽管这对我的情况没有帮助,因为在检查之后,我的图形驱动程序是最新的,在某些情况下这是一个有帮助的调试步骤
感谢大家的帮助。
- CreateDIBSection为同一图像返回不一致的位图位值
- C/C++:uint8_t位域的行为不正确且不一致
- NDK 问题:在 32 位上崩溃,在 64 位上不一致
- 在menuiteMinfo上创建位图不会负载位图
- 位掩码结果不一致
- 将opencv图像转换为gdi位图不起作用取决于图像大小
- c++ GDI 位图不想加载
- 位图显示不正确
- 如何在不使用外部库的情况下加载到 8 位C++位图图像
- 有没有办法在不复制所有像素的情况下将现有的像素数组转换为位图
- 将效果应用于输出而不是位图
- 使用 DLL 运行时,按钮上不显示位图
- 将位图从C++DLL传递回C#时的不一致行为
- 创建内存设备背景信息…对于位图,而不是设备(不是显示)
- 当切换到向量而不是数组时,位图加载中断
- 位图是拉伸而不是平铺
- C ++,位图不会显示?
- 当位图文件的行大小不是 4 的倍数时,我们应该如何处理它?
- c++类中使用位字段的属性不一致
- 写入文件的WIN API C++本地位图资源不可见