C语言中快速获取BITMAP文件/HBITMAP宽高的方法
获取位图宽高的最快方式(C语言/Windows平台)
方法一:从已加载的HBITMAP对象获取
这是加载位图后最直接高效的方式,通过GetObject函数读取HBITMAP对应的BITMAP结构体,直接提取宽高:
// 在加载bmp对象后添加这段代码 BITMAP bmpInfo; GetObject(bmp, sizeof(BITMAP), &bmpInfo); int bmpWidth = bmpInfo.bmWidth; int bmpHeight = bmpInfo.bmHeight;
把你的循环替换为:
for(int i = 0; i < bmpHeight; i++){ for(int j = 0; j < bmpWidth; j++){ COLORREF co = GetPixel(memdc, j, i); texturemap[i][j] = (COLORREF) (GetRValue(co)<<16)|(GetGValue(co)<<8)|GetBValue(co); } }
方法二:直接从BMP文件读取(无需加载位图)
如果不需要加载整个位图,直接读取文件头是更快的选择。BMP文件的BITMAPINFOHEADER结构体中存储了宽高信息,只需读取文件前半段内容即可:
#include <stdio.h> typedef struct { unsigned short bfType; unsigned int bfSize; unsigned short bfReserved1; unsigned short bfReserved2; unsigned int bfOffBits; } BITMAPFILEHEADER; typedef struct { unsigned int biSize; int biWidth; int biHeight; unsigned short biPlanes; unsigned short biBitCount; unsigned int biCompression; unsigned int biSizeImage; int biXPelsPerMeter; int biYPelsPerMeter; unsigned int biClrUsed; unsigned int biClrImportant; } BITMAPINFOHEADER; void getBmpSizeFromFile(const char* filename, int* width, int* height) { FILE* fp = fopen(filename, "rb"); if (!fp) return; BITMAPFILEHEADER fileHeader; fread(&fileHeader, sizeof(BITMAPFILEHEADER), 1, fp); // 验证是否为BMP文件(标识为"BM") if (fileHeader.bfType != 0x4D42) { fclose(fp); return; } BITMAPINFOHEADER infoHeader; fread(&infoHeader, sizeof(BITMAPINFOHEADER), 1, fp); *width = infoHeader.biWidth; *height = abs(infoHeader.biHeight); // 高度可能为负(表示位图顶向下存储) fclose(fp); }
调用示例:
int width, height; getBmpSizeFromFile(tex_name, &width, &height);
额外优化:替换GetPixel提升效率
你当前用GetPixel循环读取像素的效率极低,建议改用GetDIBits批量读取像素数据,大幅提升速度:
// 替换原循环代码 BITMAPINFO bmpInfo = {0}; bmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); GetDIBits(memdc, bmp, 0, bmpHeight, NULL, &bmpInfo, DIB_RGB_COLORS); // 分配内存存储像素 COLORREF* pixels = (COLORREF*)malloc(bmpWidth * bmpHeight * sizeof(COLORREF)); GetDIBits(memdc, bmp, 0, bmpHeight, pixels, &bmpInfo, DIB_RGB_COLORS); // 转存到texturemap for(int i = 0; i < bmpHeight; i++){ for(int j = 0; j < bmpWidth; j++){ COLORREF co = pixels[i * bmpWidth + j]; texturemap[i][j] = (GetRValue(co)<<16)|(GetGValue(co)<<8)|GetBValue(co); } } free(pixels);
内容的提问来源于stack exchange,提问作者Humanagon
相关产品推荐
相关产品推荐

