关于用C++读取BMP文件的一些问题

在做一个多媒体作业,主要是在控制台下做,现在有些问题搞不清楚。首先,在ifstream中可以直接把bmp文件读进来么?为什么读取后用sizeof函数查看长度只有144字节... 在做一个多媒体作业,主要是在控制台下做,现在有些问题搞不清楚。
首先,在ifstream中可以直接把bmp文件读进来么?为什么读取后用sizeof函数查看长度只有144字节?
然后在fread中,buffer是填入ifstream的变量名称么?在后面的*FILE中填入的文件格式,如何将其直接导入到BITMAPFILEHEADER中呢?
谢谢大侠指点!
读取之后,怎么在控制台下直接显示出BMP图像呢?
能否具体一点,函数能在MSDN中查到。。已经加分了~多谢大家!

关于SelectObject的使用,其中的hdc应该怎么初始化呢?
既然创建了可视却为空~最后一次加分!多谢大家!
展开
 我来答
L_o_o_n_i_e
2010-03-16 · TA获得超过4.2万个赞
知道大有可为答主
回答量:8507
采纳率:38%
帮助的人:5166万
展开全部
BMP 文件分几个层次 读下去。
第一部分是 文件头:
BITMAPFILEHEADER bmfHeader;
读入的字节数是 sizeof(bmfHeader)
后面几个部分的读法,与前面获得的参数有关。
信息头偏移量:read_bmp_o = bmfHeader.bfOffBits / 8;
BITMAPINFOHEADER 读 信息头 结构
BITMAPINFO 读 信息
再由上面信息决定如何读下面的。几位颜色的 BMP,用调色盘的 还是RGB, 还是黑白,还是灰色。是否压缩,是否word对齐。
下面给你MFC的码,你看懂后可以改写成你的普通C++程序:
BOOL CVPICDoc::LoadBMPImage(LPCTSTR sBMPFile, CBitmap &bitmap, CPalette *pPal)
{
BITMAPFILEHEADER bmfHeader;
Read file header
CFile file;
if( !file.Open( sBMPFile, CFile::modeRead) ) return FALSE;
if (file.Read((LPSTR)&bmfHeader, sizeof(bmfHeader)) != sizeof(bmfHeader)) return FALSE;
// Check File type should be 'BM'
if (bmfHeader.bfType != ((WORD) ('M' << 8) | 'B'))
return FALSE;
read_bmp_o = bmfHeader.bfOffBits / 8;
// Get length of the remainder of the file and allocate memory
DWORD nPackedDIBLen = file.GetLength() - sizeof(BITMAPFILEHEADER);
HGLOBAL hDIB = ::GlobalAlloc(GMEM_FIXED, nPackedDIBLen);
if (hDIB == 0) return FALSE;
// Read the remainder of the bitmap file.
// BITMAPINFOHEADER + possible-Color-Table + DIB-bits
if (file.ReadHuge((LPSTR)hDIB, nPackedDIBLen) != nPackedDIBLen )
{::GlobalFree(hDIB);
return FALSE;
}
BITMAPINFOHEADER &bmiHeader = *(LPBITMAPINFOHEADER)hDIB ;
BITMAPINFO &bmInfo = *(LPBITMAPINFO)hDIB ;
read_bmp_w = bmiHeader.biWidth;
read_bmp_h = bmiHeader.biHeight;
read_bmp_c = bmiHeader.biBitCount;
read_bmp_size = bmiHeader.biSizeImage;
if (read_bmp_size == 0) {
read_bmp_size = ((((read_bmp_w * read_bmp_c) + 31) & ~31) >> 3) * read_bmp_h;
};
read_bmp_l = read_bmp_size / read_bmp_h; // scan line width
// If bmiHeader.biClrUsed is zero we have to infer the number
// of colors from the number of bits used to specify it.
int nColors = bmiHeader.biClrUsed ? bmiHeader.biClrUsed :
1 << bmiHeader.biBitCount;
LPVOID lpDIBBits;
if( bmInfo.bmiHeader.biBitCount > 8 )
lpDIBBits = (LPVOID)((LPDWORD)(bmInfo.bmiColors + bmInfo.bmiHeader.biClrUsed) +
((bmInfo.bmiHeader.biCompression == BI_BITFIELDS) ? 3 : 0));
else
lpDIBBits = (LPVOID)(bmInfo.bmiColors + nColors);
// Create the logical palette
if( pPal != NULL )
{
// Create the palette
if( nColors <= 256 )
{
UINT nSize = sizeof(LOGPALETTE) + (sizeof(PALETTEENTRY) * nColors);
LOGPALETTE *pLP = (LOGPALETTE *) new BYTE[nSize];
pLP->palVersion = 0x300;
pLP->palNumEntries = nColors;
for( int i=0; i < nColors; i++)
{
pLP->palPalEntry[i].peRed = bmInfo.bmiColors[i].rgbRed;
pLP->palPalEntry[i].peGreen = bmInfo.bmiColors[i].rgbGreen;
pLP->palPalEntry[i].peBlue = bmInfo.bmiColors[i].rgbBlue;
pLP->palPalEntry[i].peFlags = 0;
}
pPal->CreatePalette( pLP );
delete[] pLP;
}
}
CClientDC dc(NULL);
CPalette* pOldPalette = NULL;
if( pPal )
{
pOldPalette = dc.SelectPalette( pPal, FALSE );
dc.RealizePalette();
}
HBITMAP hBmp = CreateDIBitmap( dc.m_hDC,// handle to device context &bmiHeader, // pointer to BITMAPINFOHEADER
CBM_INIT, // initialization flag
lpDIBBits, // pointer to initialization data
&bmInfo, // pointer to bitmap color-format data
DIB_RGB_COLORS); // color-data usage
bitmap.Attach( hBmp );
if( pOldPalette )
dc.SelectPalette( pOldPalette, FALSE );
::GlobalFree(hDIB);
return TRUE;
}
--------------------------
得到 bitmap 后就可以画(显示)了。
if (pDoc->m_load_bmp == 1){
CPalette *pOldPal = pDC->SelectPalette(&GetDocument()->m_pPal, false);
pDC->RealizePalette();
CDC tmpDC;
tmpDC.CreateCompatibleDC(pDC);
CBitmap* oldBitmap = tmpDC.SelectObject(&pDoc->m_bitmap);
use_cx = pDoc->bmp_info.bmWidth;
use_cy = pDoc->bmp_info.bmHeight;
if (iIsFullScreen){ //如果全屏。。。}
pDC->StretchBlt( use_x0, use_y0, use_cx, use_cy, &tmpDC, 0, 0, pDoc->bmp_info.bmWidth, pDoc->bmp_info.bmHeight, SRCCOPY );
tmpDC.SelectObject(oldBitmap);
pDC->SelectPalette(pOldPal, false);
goto Lab_end_draw;
----------------------------
以上是MFC的,你可以改成 API
wellia0926
2010-03-13 · TA获得超过293个赞
知道小有建树答主
回答量:497
采纳率:0%
帮助的人:0
展开全部
我想你sizeof的那个变量是个结构体,里面有存放bmp文件地址的指针,纯粹个人猜测,说错了大家不要骂我
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
locke_xu89
2010-03-13
知道答主
回答量:7
采纳率:0%
帮助的人:0
展开全部
先获取这个bmp文件的id,用load什么函数就可以了……
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
7820779
2010-03-16 · TA获得超过330个赞
知道小有建树答主
回答量:390
采纳率:0%
帮助的人:387万
展开全部
你大可以这样:
用fopen打开bmp文件得到文件指针,然后用fread读取数据,之后可以直接用BITMAPFILEHEADER结构读取数据就可以了
我不想和其它人抢分
显示你可以用loadbitmap读取bmp文件,然后用selectObject选入HDC就可以了。以上两个函数都可以查得到
BeginPaint或GetDC可以得到HDC
然后响应WM_PAINT消息选入HDC
或者你可以用双缓冲也行,但你必须创建内存DC选入位图,才可以用Bitblt复制到DC上。回答完毕
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
osoon2008
2010-03-13 · 超过24用户采纳过TA的回答
知道答主
回答量:85
采纳率:0%
帮助的人:66.4万
展开全部
O,my god!

1。ifstream里面存放的文件的句柄,而是整张bmp图。

2。buffer是你要读出内容的临时存放点,*FILE则是文件句柄。

3。查bmp的文件格式,网上应该有,很久不用了想不起来,按字节数一个一个fwrite就可以了。用结构一次性导入容易有错。
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
收起 更多回答(3)
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式