如何用C++程序打开bmp文件

猪皮冻 2011-09-26 02:46:36
如何用C++写程序打开一幅BMP格式的图片啊,最好是二值的,八位的,和真彩色的程序,给提提思路也好,刚接触,一点思路都没有,各位帮帮忙吧
...全文
336 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
iblold 2011-09-26
  • 打赏
  • 举报
回复
最后加上两行

delete pBmpData;
delete pRgb;
刚才整理的时候误删了
iblold 2011-09-26
  • 打赏
  • 举报
回复

// pdat是RGBA格式,w图像的宽,h高
void Bmp2RGBA(char* caFileName, DWORD** pdat, int& w, int& h)
{
FILE* pf = fopen(caFileName, "rb");
if (pf == NULL)
return;

BITMAPFILEHEADER bm;
fread(&bm, 1, sizeof(BITMAPFILEHEADER), pf);

if (bm.bfType!=*(WORD*)"BM")
{
fclose(pf);
return;
}
BITMAPINFOHEADER bmif;
fread(&bmif, 1, sizeof(BITMAPINFOHEADER), pf);
int bmx = bmif.biWidth;
int bmy = bmif.biHeight>0?bmif.biHeight:(-bmif.biHeight);

if (bmif.biBitCount < 8 || bmif.biCompression != 0)
{
fclose(pf);
return;
}

RGBQUAD *pRgb = NULL;
if (bmif.biBitCount == 8) // 256色bmp
{
pRgb = (RGBQUAD*) new BYTE[bmif.biClrUsed * sizeof(RGBQUAD)];
fread(pRgb, bmif.biClrUsed * sizeof(RGBQUAD), 1, pf);
}

BOOL bAlpha = FALSE;
if (bmif.biBitCount == 32) bAlpha = TRUE;// 带Alpha通道

DWORD dwRealWidth = (((bmx*bmif.biBitCount)+31)>>5)<<2;
int iBitSteps = bmif.biBitCount>>3;
DWORD iSize = dwRealWidth*bmy;

BYTE* pBmpData = NULL;
int readlines = bmy;
int readszie = iSize;
int readtimes = bmy/readlines;
if (iSize > 128*1024*1024)
{
readlines = (128*1024*1024/dwRealWidth);
readszie = readlines*dwRealWidth;
readtimes = bmy/readlines + 1;
}


pBmpData = new BYTE[readszie];
fseek(pf, bm.bfOffBits, SEEK_SET);
fread(pBmpData, 1, readszie, pf);

w = bmx;
h = bmy;
*pdat = new DWORD[w * h];

int iy,ix;
BYTE btPil;
char caTmp[4];
DWORD dwDataOff = 0;
int picy = 0;
for(int n = 0; n < readtimes; ++n)
{
for (iy = 0; iy < readlines; ++iy)
{
for (ix = 0; ix < bmx; ++ix)
{
if (pRgb == NULL)
{
caTmp[0] = pBmpData[(iy * dwRealWidth + ix * iBitSteps) + 2];
caTmp[1] = pBmpData[(iy * dwRealWidth + ix * iBitSteps) + 1];
caTmp[2] = pBmpData[(iy * dwRealWidth + ix * iBitSteps)];
}
else
{
btPil = pBmpData[(iy * dwRealWidth + ix * iBitSteps)];
if (bmif.biClrUsed != 0)
{
caTmp[0] = pRgb[btPil].rgbRed;
caTmp[1] = pRgb[btPil].rgbGreen;
caTmp[2] = pRgb[btPil].rgbBlue;
}
else
{
caTmp[0] = caTmp[1] = caTmp[2] = btPil;
}

}

if (bmif.biHeight < 0) // 有时bmp图像的高会是负值,这时则不用颠倒
{
dwDataOff = (iy + picy) * bmx + ix;
}
else
{
dwDataOff = (bmy - (iy + picy) - 1) * bmx + ix;
}

caTmp[3] = 255;

if (bAlpha)
{
caTmp[3] = pBmpData[(iy * dwRealWidth + ix * iBitSteps) + 3];
}

*pdat[dwDataOff] = *(DWORD*)caTmp;

}
}
picy += readlines;
int realbits = fread(pBmpData, 1, readszie, pf);
if (realbits < readszie) readlines = realbits / dwRealWidth;
}

if (pf)
fclose(pf);
pf = NULL;
}


可以读取8、24、32位bmp,

2位或者256级灰度的图可以在上面函数中添加只要读的时候改个步长就行了
cbib_cat 2011-09-26
  • 打赏
  • 举报
回复
可以用OpenCV处理图像,很方便的。
vilnies 2011-09-26
  • 打赏
  • 举报
回复
LZ的问题应该不是这么简单吧。BMP文件有格式啊,可以根据格式读数据就行,可以看看GDI编程的有关书籍,都有例子的
luciferisnotsatan 2011-09-26
  • 打赏
  • 举报
回复
fopen,二进制打开文件

64,644

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧