www.pudn.com > bmp_info.rar > bmp_info.cpp
// bmp_info.cpp : Defines the entry point for the application. // #include "stdafx.h" #include "bmp_info.h" #include "bmpinfo.h" #define MAX_LOADSTRING 100 // Global Variables: HINSTANCE hInst; // current instance TCHAR szTitle[MAX_LOADSTRING]; // The title bar text TCHAR szWindowClass[MAX_LOADSTRING]; // the main window class name // Forward declarations of functions included in this code module: ATOM MyRegisterClass(HINSTANCE hInstance); BOOL InitInstance(HINSTANCE, int); LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM); // For (HWND hWnd, char *BmpFileName) Begin: #include#include #include BITMAPFILEHEADER bf; BITMAPINFOHEADER bi; #define WIDTHBYTES(i) ((i+31)/32*4) HANDLE hImgData; char BmpFileName[256] = "c:\\test.bmp"; // For (HWND hWnd, char *BmpFileName) end: BOOL LoadBmpFile (HWND hWnd, char *BmpFileName); void Message_Box (HWND hWnd, char content[]); int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) { UNREFERENCED_PARAMETER(hPrevInstance); UNREFERENCED_PARAMETER(lpCmdLine); // TODO: Place code here. MSG msg; HACCEL hAccelTable; // Initialize global strings LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); LoadString(hInstance, IDC_BMP_INFO, szWindowClass, MAX_LOADSTRING); MyRegisterClass(hInstance); // Perform application initialization: if (!InitInstance (hInstance, nCmdShow)) { return FALSE; } hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_BMP_INFO)); // Main message loop: while (GetMessage(&msg, NULL, 0, 0)) { if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) { TranslateMessage(&msg); DispatchMessage(&msg); } } return (int) msg.wParam; } // // FUNCTION: MyRegisterClass() // // PURPOSE: Registers the window class. // // COMMENTS: // // This function and its usage are only necessary if you want this code // to be compatible with Win32 systems prior to the 'RegisterClassEx' // function that was added to Windows 95. It is important to call this function // so that the application will get 'well formed' small icons associated // with it. // ATOM MyRegisterClass(HINSTANCE hInstance) { WNDCLASSEX wcex; wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = CS_HREDRAW | CS_VREDRAW; wcex.lpfnWndProc = WndProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = hInstance; wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_BMP_INFO)); wcex.hCursor = LoadCursor(NULL, IDC_ARROW); wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); wcex.lpszMenuName = MAKEINTRESOURCE(IDC_BMP_INFO); wcex.lpszClassName = szWindowClass; wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL)); return RegisterClassEx(&wcex); } // // FUNCTION: InitInstance(HINSTANCE, int) // // PURPOSE: Saves instance handle and creates main window // // COMMENTS: // // In this function, we save the instance handle in a global variable and // create and display the main program window. // BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) { HWND hWnd; hInst = hInstance; // Store instance handle in our global variable hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL); if (!hWnd) { return FALSE; } ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); return TRUE; } // // FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM) // // PURPOSE: Processes messages for the main window. // // WM_COMMAND - process the application menu // WM_PAINT - Paint the main window // WM_DESTROY - post a quit message and return // // LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { int wmId, wmEvent; PAINTSTRUCT ps; HDC hdc; switch (message) { case WM_COMMAND: wmId = LOWORD(wParam); wmEvent = HIWORD(wParam); // Parse the menu selections: switch (wmId) { case ID_FILE_BMPINFO: LoadBmpFile(hWnd,BmpFileName); break; case IDM_ABOUT: DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About); break; case IDM_EXIT: DestroyWindow(hWnd); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } break; case WM_PAINT: hdc = BeginPaint(hWnd, &ps); // TODO: Add any drawing code here... EndPaint(hWnd, &ps); break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; } // Message handler for about box. INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { UNREFERENCED_PARAMETER(lParam); switch (message) { case WM_INITDIALOG: return (INT_PTR)TRUE; case WM_COMMAND: if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) { EndDialog(hDlg, LOWORD(wParam)); return (INT_PTR)TRUE; } break; } return (INT_PTR)FALSE; } 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; int gray; // 图像灰度值 char msg_content[102400] = ""; char msg_tmp[102400] = ""; 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 :%-8d\ File Type :%-8d\ Offbits :%-8d\ Width :%-8d\n\ Heigth :%-8d\ Bit Count :%-8d\ Compression :%-8d\ Image Size :%-8d\n\ XPelsPerMeter :%-8d\ YPelsPerMeter :%-8d\ ClrUsed :%-8d\ ClrImportant :%-8d\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; // 灰度值计算方法0.3Red+0.59Green+0.11Blue gray=(lpRGB->rgbRed)*0.3+(lpRGB->rgbGreen)*0.59+(lpRGB->rgbBlue)*0.11; if ( i%1 == 0) { strcpy(msg_tmp, ""); sprintf(msg_tmp,"[%-3d]:R = %-3d,G = %-3d,B = %-3d,G = %-3d ",\ i, pPal->palPalEntry[i].peRed, pPal->palPalEntry[i].peGreen, pPal->palPalEntry[i].peBlue, gray); strcat(msg_content, msg_tmp); } if ( (i+1)%4 == 0) strcat(msg_content, "\n"); 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[102400]; 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); }