【小记】BITMAP To BMP 调用 GetDIBits 引发栈内存损坏问题
BITMAP bitmap; if (!GetObject(hBitmap, sizeof(bitmap), &bitmap)) { // 外部传入 hBitmap return false; } // 创建位图信息头 BITMAPINFO bitInfo; BITMAPINFOHEADER& bi = bitInfo.bmiHeader; bi.biWidth = bitmap.bmWidth; bi.biHeight = bitmap.bmHeight; bi.biPlanes = 1; bi.biBitCount = bitmap.bmBitsPixel; // 这里为 8 位 bi.biCompression = BI_RGB; bi.biSizeImage = 0; bi.biXPelsPerMeter = 0; bi.biYPelsPerMeter = 0; bi.biClrUsed = 0; bi.biClrImportant = 0; bi.biSize = sizeof(BITMAPINFOHEADER); // 创建位图文件头 BITMAPFILEHEADER bf; bf.bfType = 0x4D42; // "BM" bf.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + bitmap.bmWidthBytes * bitmap.bmHeight; bf.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER); bf.bfReserved1 = 0; bf.bfReserved2 = 0; // 创建一个足够大的缓冲区来存储位图文件头、位图信息头和像素数据 bufferSize = bf.bfSize; buffer = (unsigned char*)GlobalAlloc(GMEM_FIXED, bufferSize); if (buffer == nullptr) { return false; } // 将位图文件头、位图信息头和像素数据复制到缓冲区 (或直接写入文件) memcpy(buffer, &bf, sizeof(bf)); memcpy(buffer + sizeof(bf), &bi, sizeof(bi)); HDC hdc = CreateCompatibleDC(NULL); if (hdc == NULL) { return false; } if (!GetDIBits(hdc, hBitmap, 0, (UINT)bitmap.bmHeight, buffer + bf.bfOffBits, &bitInfo, DIB_RGB_COLORS)) { GlobalFree(buffer); bufferSize = 0; return false; } DeleteObject(bitmap); ReleaseDC(hdc); return true;
太忙,简单说一下:
当 BMP 小于 16 位时,需要额外的内存空间来存储颜色数据。只传入一个 BITMAPINFOHEADER 是不行的,在 GetDIBits 调用后会引发栈内存损坏导致程序崩溃。需要传入一个完整的 BITMAPINFO 类型才行。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具