www.pudn.com > bmp_info.rar > bmpinfo.cpp


#include "bmpinfo.h" 
#include "stdafx.h" 
 
BITMAPFILEHEADER   bf; 
BITMAPINFOHEADER   bi; 
 
#define WIDTHBYTES(i)  ((i+31)/32*4) 
 
HANDLE hImgData; 
 
BOOL LoadBmpFile (HWND hWnd,char *BmpFileName) 
{    
    HFILE               hf; //文件句柄 
    LPBITMAPINFOHEADER  lpImgData; //指向BITMAPINFOHEADER结构的指针 
    LOGPALETTE          *pPal; //指向逻辑调色板结构的指针 
    LPRGBQUAD           lpRGB; //指向RGBQUAD结构的指针 
    HLOCAL              hPal; //存储调色板的局部内存句柄 
    DWORD  	    	    LineBytes;  //每一行的字节数 
    DWORD 	    	    ImgSize;   //实际的图象数据占用的字节数 
    DWORD               NumColors; //实际用到的颜色数 ,即调色板数组中的颜色个数 
    DWORD               i; 
 
	char msg_content[1024] = ""; 
	char msg_tmp[1024] = ""; 
 
    if((hf=_lopen(BmpFileName,OF_READ))==HFILE_ERROR){ 
		sprintf(msg_tmp,"bmp file: %s can not be found! \n", BmpFileName); 
		strcpy(msg_content, msg_tmp); 
		Message_Box(hWnd, msg_content); 
        return FALSE; //打开文件错误,返回 
    } 
 
    //将BITMAPFILEHEADER结构从文件中读出,填写到bf中 
    _lread(hf,(LPSTR)&bf,sizeof(BITMAPFILEHEADER));  
    //将BITMAPINFOHEADER结构从文件中读出,填写到bi中 
    _lread(hf,(LPSTR)&bi,sizeof(BITMAPINFOHEADER)); 
 
	sprintf(msg_tmp,"the infomation of bitmap :\n\ 
File Size     :%d\n\ 
File Type     :%d\n\ 
Offbits       :%d\n\ 
Width         :%d\n\ 
Heigth        :%d\n\ 
Bit Count     :%d\n\ 
Compression   :%d\n\ 
Image Size    :%d\n\ 
XPelsPerMeter :%d\n\ 
YPelsPerMeter :%d\n\ 
ClrUsed       :%d\n\ 
ClrImportant  :%d\n", 
				bf.bfSize, 
				bf.bfType, 
				bf.bfOffBits, 
				bi.biWidth, 
				bi.biHeight, 
				bi.biBitCount, 
				bi.biCompression, 
				bi.biSizeImage, 
				bi.biXPelsPerMeter, 
				bi.biYPelsPerMeter, 
				bi.biClrUsed, 
				bi.biClrImportant); 
	strcpy(msg_content, msg_tmp); 
 
    //LineBytes为每一行的字节数 
    LineBytes=(DWORD)WIDTHBYTES(bi.biWidth*bi.biBitCount); 
    //ImgSize为实际的图象数据占用的字节数 
    ImgSize=(DWORD)LineBytes*bi.biHeight; 
    //NumColors为实际用到的颜色数 ,即调色板数组中的颜色个数 
    if(bi.biClrUsed!=0) 
        NumColors=(DWORD)bi.biClrUsed; //如果bi.biClrUsed不为零,就是本图象实际            
    //用到的颜色数 
    else //否则,用到的颜色数为2的biBitCount次方 
        switch(bi.biBitCount){ 
       	case 1: 
            NumColors=2; 
            break; 
        case 4: 
            NumColors=16; 
            break; 
        case 8: 
            NumColors=256; 
            break; 
        case 24: 
            NumColors=0; //对于真彩色图,没用到调色板 
            break; 
        default: 
            //不处理其它的颜色数,认为出错。 
			strcpy(msg_content, "Invalid color numbers! \n"); 
			Message_Box(hWnd, msg_content); 
            _lclose(hf); 
            return FALSE; //关闭文件,返回FALSE 
        } 
 
    if(bf.bfOffBits!=(DWORD)(NumColors*sizeof(RGBQUAD)+ 
        sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER))) 
    { 
        //计算出的偏移量与实际偏移量不符,一定是颜色数出错 
		strcpy(msg_content, "Invalid color numbers! \n"); 
		Message_Box(hWnd, msg_content); 
        _lclose(hf); 
     	return FALSE; //关闭文件,返回FALSE 
  	} 
  	  
    bf.bfSize=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+NumColors 
        *sizeof(RGBQUAD)+ImgSize; 
 
    //分配内存,大小为BITMAPINFOHEADER结构长度加调色板+实际位图数据 
  	if((hImgData=GlobalAlloc(GHND,(DWORD)(sizeof(BITMAPINFOHEADER)+ 
        NumColors*sizeof(RGBQUAD)+ImgSize)))==NULL) 
    { 
		//分配内存错误 
		strcpy(msg_content, "Error alloc memory! \n"); 
		Message_Box(hWnd, msg_content); 
   		_lclose(hf); 
    	return FALSE; //关闭文件,返回FALSE 
    } 
 
  	//指针lpImgData指向该内存区 
  	lpImgData=(LPBITMAPINFOHEADER)GlobalLock(hImgData);  
 
  	//文件指针重新定位到BITMAPINFOHEADER开始处 
  	_llseek(hf,sizeof(BITMAPFILEHEADER),SEEK_SET); 
 
  	//将文件内容读入lpImgData 
  	_hread(hf,(char *)lpImgData,(long)sizeof(BITMAPINFOHEADER) 
        +(long)NumColors*sizeof(RGBQUAD)+ImgSize); 
  	_lclose(hf); //关闭文件 
 
 	if(NumColors!=0) //NumColors不为零,说明用到了调色板 
  	{                     
    	//为逻辑调色板分配局部内存,大小为逻辑调色板结构长度加NumColors个          
    	//PALETTENTRY大小 
   		hPal=LocalAlloc(LHND,sizeof(LOGPALETTE) +  
   		    NumColors* sizeof(PALETTEENTRY)); 
 
        //指针pPal指向该内存区 
    	pPal =(LOGPALETTE *)LocalLock(hPal); 
 
     	//填写逻辑调色板结构的头 
     	pPal->palNumEntries = NumColors; 
     	pPal->palVersion    = 0x300; 
 
     	//lpRGB指向的是调色板开始的位置 
     	lpRGB = (LPRGBQUAD)((LPSTR)lpImgData + (DWORD)sizeof(BITMAPINFOHEADER)); 
 
     	//填写每一项 
     	for (i = 0; i < NumColors; i++) 
     	{ 
            pPal->palPalEntry[i].peRed=lpRGB->rgbRed; 
            pPal->palPalEntry[i].peGreen=lpRGB->rgbGreen; 
            pPal->palPalEntry[i].peBlue=lpRGB->rgbBlue; 
            pPal->palPalEntry[i].peFlags=(BYTE)0; 
            lpRGB++; //指针移到下一项 
        } 
 
        //释放局部内存 
        LocalUnlock(hPal); 
        LocalFree(hPal); 
    } 
 
    GlobalUnlock(hImgData); //解锁内存区 
	Message_Box(hWnd, msg_content); 
 
    return TRUE; //成功返回 
} 
 
// Show the Message 
void Message_Box(HWND hWnd, char content[]) 
{ 
	WCHAR wchar_outstring[1024]; 
	swprintf(wchar_outstring, L"%S", content); 
	LPCWSTR p_outstring = wchar_outstring; 
 
	WCHAR wchar_outtitle[255]; 
	swprintf(wchar_outtitle, L"%S", "Message Box"); 
	LPCWSTR p_outtitle = wchar_outtitle; 
 
	MessageBox(hWnd, p_outstring, p_outtitle, MB_OK); 
}