如何从像素缓冲区创建 Win32 HBITMAP

2023-12-12

我尝试从像素缓冲区创建 HBITMAP 并显示它。这是我创建 HBITMAP 的代码

char buffer[640 * 480 * 3];
memset(buffer, 255, 640 * 480 * 3);
BITMAPINFO bm = { sizeof(BITMAPINFOHEADER),
        640,
        480, 1, 24,
        BI_RGB, 640 * 480 * 3, 0, 0, 0, 0 };
HBITMAP imageBmp = CreateDIBSection(hdc, &bm, DIB_RGB_COLORS, (void**)buffer, 0, 0);
if (imageBmp == NULL) {
    DWORD lastError = GetLastError();
    return;
}

这是显示它的代码:

 HDC imageDC = CreateCompatibleDC(NULL);     // create an offscreen DC
SelectObject(imageDC, imageBmp);  // put the loaded image into our DC
RECT rect;
GetClientRect(hDlg, &rect);
BitBlt(
    hdc,         // tell it we want to draw to the screen
    0, 0,            // as position 0,0 (upper-left corner)
    rect.right - rect.left,   // width of the rect to draw
    rect.bottom - rect.top,   // height of the rect
    imageDC,        // the DC to get the rect from (our image DC)
    0, 0,            // take it from position 0,0 in the image DC
    SRCCOPY         // tell it to do a pixel-by-pixel copy
);

我期待看到白色图像,但得到的是黑色窗纱。我很确定我的显示代码是正确的,但不知道为什么创建 HBITMAP 的代码是错误的。


CreateDIBSection已经通过返回一个分配的缓冲区ppvBits对你的争论,所以它会覆盖你的buffer多变的。来自文档(强调我的):

ppvBits 指向变量的指针receives一个指向 DIB 位值的位置。

您的代码所需的修复:

  • 删除创建数组的代码。
  • 传递一个指针的地址ppvBits范围。
  • 仅设置像素after成功调用CreateDIBSection.
char* buffer = NULL;
BITMAPINFO bm = { sizeof(BITMAPINFOHEADER),
        640,
        480, 1, 24,
        BI_RGB, 640 * 480 * 3, 0, 0, 0, 0 };
HBITMAP imageBmp = CreateDIBSection(hdc, &bm, DIB_RGB_COLORS, (void**) &buffer, 0, 0);
if (imageBmp == NULL) {
    DWORD lastError = GetLastError();
    return;
}
memset(buffer, 255, 640 * 480 * 3);

Note:

确保在生产代码中,通过将位图宽度与下一个对齐来正确计算大小DWORD边界,如文章所述“DIB 及其用途":

计算位图的大小并不困难:

biSizeImage = ((((biWidth * biBitCount) + 31) & ~31) >> 3) * biHeight

疯狂的舍入和移位说明了位图是 在每条扫描线的末尾进行 DWORD 对齐。

在你的样本中,640 * 480 * 3给出正确的结果只是因为宽度640已经可以被 4 整除。对于宽度641你的公式会失败,而文章中引用的公式会给出正确的结果。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何从像素缓冲区创建 Win32 HBITMAP 的相关文章

  • NtDll 真的导出 C 运行时函数吗?我可以在我的应用程序中使用这些函数吗?

    我在查看 Windows 10 计算机上的 NtDll 导出表 发现它导出标准 C 运行时函数 例如memcpy sprintf strlen etc 这是否意味着我可以在运行时动态调用它们LoadLibrary and GetProcAd
  • MoveWindow死锁?

    我在线程 A 上有一个窗口 它在某个时刻 由于在其 wndproc 上收到消息 触发线程 B 上的操作 然后等待该操作完成 使用某种同步机制 然后线程B调用MoveWindow 在线程 A 的窗口 例如标准文本框 内移动子窗口 此时程序由于
  • 使用 CreateProcessAsUser 和 CreateEnvironmentBlock 创建进程后未设置 Clientname

    我编写了一个在本地系统帐户下运行的 C 服务 当用户登录终端服务器时 我用它来生成一个进程 该服务实现了OnSessionChange方法并接收SessionChangeDescription具有相应SessionID的消息 我使用此 Se
  • C++使用太多CPU

    好的 我正在创建一个游戏 但它使用了太多的 cpu 但它没有使用太多的内存 cpu确实增加和减少 我的游戏中有太多计时器 当我不再使用计时器时 我会杀死计时器 因此这应该会导致问题 但我认为导致问题的原因是我的消息队列中有太多消息 我有一台
  • 在 Win7 登录屏幕上运行应用程序[重复]

    这个问题在这里已经有答案了 我想通过服务在 Windows 7 的登录屏幕上运行应用程序 我对此进行了长期研究并尝试了不同的方法 但不幸的是到目前为止还没有完全成功 我设法在当前登录用户的锁定屏幕上运行该应用程序 起初我认为这就是我基本上试
  • 在没有主窗口的 MFC 应用程序中创建多个对话框,它们成为彼此的子级

    标题已更新 继从this https stackoverflow com questions 2729371 creating multiple mfc dialogs through com strange behaviour问题 现在我
  • 在 Windows 7 上连接到高于 10 的 COM 端口时出现无效句柄错误

    我开发了一个简单的串行端口应用程序 可以在低于 10 的 COM 端口 COM9 COM8 COM1 上正常工作 但是 当我的设备连接到高于 10 的端口 例如 COM11 时 它无法连接 并且我收到 INVALID HANDLE 我的代码
  • 有效地将位图数组转换为视频

    使用 Jcodec 库 我成功地从 Bitmap 对象数组生成视频文件并将其存储在 Android 文件系统上 但是 那encoding时间太长了 我考虑过缩小每个位图以加快速度 但这似乎不起作用 尽管进行了广泛的研究 我还是很难找到有用的
  • Bitmap.getPixels() 中的 IllegalArgumentException

    我想将数据从位图复制到int using getPixels 这是我当前的代码 int pixels new int myBitmap getHeight myBitmap getWidth myBitmap getPixels pixel
  • 可以在滚动条上绘画吗?

    是否可以在 TMemo TListbox 等标准控件的滚动条上进行绘制 我所需要的只是在滚动条上绘制一些基本形状 并且我试图避免从 stratch 实现整个滚动内容 有什么指点吗 蒂亚 确实有可能 你可能想看一下WM NCPAINT消息 这
  • 生成唯一的机器 ID

    我需要编写一个函数来生成一个对于运行 Windows 操作系统的给定机器来说唯一的 id 目前 我正在使用 WMI 查询各种硬件参数 并将它们连接在一起并对它们进行哈希处理以得出唯一的 id 我的问题是 我应该使用哪些建议参数 目前 我使用
  • 在flex中调用Win32 API设置窗口显示亲和力

    我使用 Adob e Air 创建了一个 Flex 桌面应用程序 我需要保护应用程序不被捕获 通过改变应用程序的窗口显示亲和力 可以保护应用程序不被捕获 如何在flex中使用win API 还有其他方法可以保护窗口不被捕获吗 首先你必须确保
  • 如何从后台线程有效地对 Delphi 6 框架或表单执行图像流预览?

    我有一个 Delphi 6 应用程序 用于接收和处理来自外部摄像头的图像流 我将代码放在后台线程上 因为它占用大量 CPU 而且我不希望它干扰在主线程上运行的用户界面代码 我想使用我从相机的 JPEG 帧创建的 TBitmap 来更新表单或
  • C 和 Windows API 之间有什么关系?

    我查看了有关 SO 的其他一些问题 不清楚 c 是构建在 WINAPI 之上 之下还是旁边 例如 有人可以用纯 c 语言编写一些能够打开窗口的东西 或者他们需要使用 windows api 吗 我注意到打开文件 fopen 的 c 库 版本
  • 使用 WinAPI 的窗口截图

    如何使用 WinAPI 和 C 制作程序窗口的屏幕截图 要结束了WM PAINT 0x000F 发送到窗口的消息 我想对其进行屏幕截图 wParam HDC处理 但我的图片框中没有屏幕截图 如果我发送一个WM CLOSE消息 一切正常 目标
  • MFC中如何获取子菜单?

    我正在尝试获取一个子菜单 以便我可以在显示它之前对其进行更改 所以我创建了一个OnInitMenu 我的窗口的处理程序 我本来计划使用pMenu gt GetMenuItemInfo 获取子菜单 然而 这似乎行不通 为了找到我想要的菜单 我
  • 如何检测我的应用程序是否在虚拟机中运行?

    如何检测 NET 或 Win32 我的应用程序是否在虚拟机中运行 这就是我使用的 using var searcher new System Management ManagementObjectSearcher Select from W
  • 判断两个文件是否属于同一个卷

    我正在参与一些 ntfs 硬链接项目 我想知道如何确定两个文件 具有完整路径 是否属于同一卷 有几个选项可用于查找与文件关联的卷信息 找到两个文件的根路径 然后使用GetVolumeInformation http msdn microso
  • 为什么是 HSHELL_WINDOWDESTROYED、HSHELL_WINDOWCREATED?

    MSDN ShellProc功能 RegisterShellHookWindow功能 HSHELL WINDOWCREATED gt A top level unowned window has been created HSHELL WI
  • AS3 - 在正好 23 个空 Alpha 通道处,下面的图像停止绘制

    我注意到 在尝试绘制大量圆圈时 偶尔会出现某种视觉错误 某些圆圈无法正确绘制 好吧 我缩小了范围 并注意到如果同一位置有 23 个或更多 alpha 值为 00 的对象 则下面的对象不会绘制 它似乎是在逐个像素的基础上进行的 因为图像的某些

随机推荐