// #include <windows.h> #include <iostream> #include <stdio.h> #include <windows.h> #include <fstream> #include <string> #include "define.h" using namespace std; LPCWSTR szClass = TEXT("test1001"); LPCWSTR szTitle = TEXT("BMP"); //窗口过程 LRESULT CALLBACK __WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); /********************************************************************************* 其它部分 **********************************************************************************/ int biWidth; //图像宽 int biHeight; //图像高 int biBitCount; //图像类型,每像素位数 //RGBQUAD *pColorTable; //颜色表指针 unsigned char *pBmpBuf; //存储图像数据 int lineByte; //图像数据每行字节数 /** * 函数名: readBmp * 参 数: bmpName -- bmp文件名 * 功 能: 读入bmp文件,并获取相应的信息 */ bool readBmp(char *bmpName) { FILE *fp; if ((fp = fopen(bmpName, "rb")) == NULL) //以二进制的方式打开文件 { cout << "The file " << bmpName << "was not opened" << endl; return FALSE; } if (fseek(fp, sizeof(BITMAPFILEHEADER), SEEK_CUR)) //跳过BITMAPFILEHEADE { cout << "跳转失败" << endl; return FALSE; } BITMAPINFOHEADER infoHead; fread(&infoHead, sizeof(BITMAPINFOHEADER), 1, fp); //从fp中读取BITMAPINFOHEADER信息到infoHead中,同时fp的指针移动 biWidth = infoHead.biWidth; biHeight = infoHead.biHeight; biBitCount = infoHead.biBitCount; lineByte = (biWidth*biBitCount / 8 + 3) / 4 * 4; //lineByte必须为4的倍数 //24位bmp没有颜色表,所以就直接到了实际的位图数据的起始位置 pBmpBuf = new unsigned char[lineByte * biHeight]; fread(pBmpBuf, sizeof(char), lineByte * biHeight, fp); fclose(fp); //关闭文件 return TRUE; } /** * 函数名: saveBmp * 参 数: bmpName -- bmp文件名 * 功 能: 将bmp位图文件的相关信息,写入新创建的文件中 */ bool saveBmp(char *bmpName) { FILE *fp; if ((fp = fopen(bmpName, "wb")) == NULL) //以二进制写入方式打开 { printf("打开文件失败"); return FALSE; } //设置BITMAPFILEHEADER参数 BITMAPFILEHEADER fileHead; fileHead.bfType = 0x4D42; fileHead.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + lineByte * biHeight; fileHead.bfReserved1 = 0; fileHead.bfReserved2 = 0; fileHead.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER); fwrite(&fileHead, sizeof(BITMAPFILEHEADER), 1, fp); //设置BITMAPINFOHEADER参数 BITMAPINFOHEADER infoHead; infoHead.biSize = 40; infoHead.biWidth = biWidth; infoHead.biHeight = biHeight; infoHead.biPlanes = 1; infoHead.biBitCount = biBitCount; infoHead.biCompression = BI_RGB; infoHead.biSizeImage = lineByte * biHeight; infoHead.biXPelsPerMeter = 0; infoHead.biYPelsPerMeter = 0; infoHead.biClrUsed = 0; infoHead.biClrImportant = 0; //写入 fwrite(&infoHead, sizeof(BITMAPINFOHEADER), 1, fp); fwrite(pBmpBuf, sizeof(char), lineByte * biHeight, fp); fclose(fp); //关闭文件 return TRUE; } void DeleteBmp() { delete[]pBmpBuf; //释放内存 } /** * 函数名: work * 功 能: 处理位图信息,并将位图数据保存到ImageData文件中 */ void work(char* filename) { // char readFileName[] = "test.BMP"; //定义要读入的文件名 // if (FALSE == readBmp(readFileName)) if (false == readBmp(filename)) printf("read file error!\n"); //输出图像的信息 cout << "Width = " << biWidth << " Height = " << biHeight << " biBitCount=" << biBitCount << endl; } //GDI部分,绘图 HDC g_hdc, g_mdc, g_bufdc; HBITMAP bmps[2];//0 是down 1 是背景 //显示相关初始化 void DeviceInit(HWND hwnd)//, LPCWSTR bmpname { HBITMAP bmp; g_hdc = GetDC(hwnd); #if(1) g_mdc = CreateCompatibleDC(g_hdc); g_bufdc = CreateCompatibleDC(g_hdc);//再创建一个和hdc兼容的缓冲DC bmp = CreateCompatibleBitmap(g_hdc, biWidth, biHeight); //建一个和窗口兼容的空的位图对象 SelectObject(g_mdc, bmp); //载入资源 // bmps[0] = (HBITMAP)LoadImage(NULL,bmpname, IMAGE_BITMAP, 40, 40, LR_LOADFROMFILE); HFONT hFont = CreateFont(20, 0, 0, 0, 700, 0, 0, 0, GB2312_CHARSET, 0, 0, 0, 0, TEXT("微软雅黑")); SelectObject(g_mdc, hFont); SetBkMode(g_mdc, TRANSPARENT); //设置文字显示背景透明 SetTextColor(g_mdc, RGB(0, 0, 0)); #endif } //显示 void DeviceDisplay(unsigned char* bmpda) { wchar_t strings[100]; COLORREF rgba; RGB_t rgb_t; unsigned char *pbmpdata = bmpda; for (int i = 0;i<biHeight; i++) { for (int j = 0; j < biWidth;j++) {
<span style="white-space:pre"> </span>//这里比较关键了,
<span style="white-space:pre"> </span>//1:BMP文件24位颜色 存储顺序BGR;2:3*j表示每个像素占三个UCHAR int b = *(pbmpdata + (biHeight - 1 - i)*lineByte + 3 * j + 0); int g = *(pbmpdata + (biHeight - 1 - i)*lineByte + 3 * j + 1); int r = *(pbmpdata + (biHeight - 1 - i)*lineByte + 3 * j + 2); int a = 0; // rgba = (((r)+((g) << 8)) + (((b) << 16) + ((a) << 24))); SetPixel(g_mdc, j, i, (((r)+((g) << 8)) + (((b) << 16) + ((a) << 24)))); // SetPixel(g_hdc, j, i, rgba); // SetPixel(g_hdc, j, i, RGB(r, g, b)); } } BitBlt(g_hdc, 0, 0, biWidth, biHeight, g_mdc, 0, 0, SRCCOPY); } /**********************************************************************************/ int main(int argc, char *argv[]) { if (argc < 2) work("test.bmp"); else work(argv[1]); HINSTANCE hIns = ::GetModuleHandle(0); WNDCLASSEX wc; wc.cbSize = sizeof(wc); wc.style = CS_HREDRAW | CS_VREDRAW; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hIns; wc.hIcon = LoadIcon(0, IDI_APPLICATION); wc.hIconSm = 0; wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); wc.hCursor = LoadCursor(0, IDC_ARROW); wc.lpfnWndProc = __WndProc; wc.lpszMenuName = NULL; wc.lpszClassName = szClass; if (!RegisterClassEx(&wc)) exit(0); // DWORD style = WS_OVERLAPPEDWINDOW; //细边框窗口 DWORD style = WS_POPUP | WS_THICKFRAME; DWORD styleEx = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE; //根据图片大小生成窗口 RECT rect; if ((biWidth!=0)&&(biHeight!=0)) rect = { 0, 0,biWidth,biHeight }; else rect = { 0, 0, 800, 600 }; AdjustWindowRectEx(&rect, style, false, styleEx); HWND hWnd = CreateWindowEx(styleEx, szClass, szTitle, style, 0, 0, rect.right - rect.left, rect.bottom - rect.top, 0, 0, hIns, 0); if (hWnd == 0) exit(0); UpdateWindow(hWnd); ShowWindow(hWnd, SW_SHOW); //TODO, init this DeviceInit(hWnd); MSG msg = { 0 }; while (msg.message != WM_QUIT) { if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) { TranslateMessage(&msg); DispatchMessage(&msg); } else { //TODO, do this DeviceDisplay(pBmpBuf); } } return 0; } LRESULT CALLBACK __WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { PAINTSTRUCT ps; HDC hdc; switch (msg) { case WM_DESTROY: PostQuitMessage(0); break; case WM_PAINT: hdc = BeginPaint(hWnd, &ps); EndPaint(hWnd, &ps); break; case WM_KEYDOWN: switch (wParam) { case VK_ESCAPE: //按Esc键退出程序 PostQuitMessage(0); break; } } return DefWindowProc(hWnd, msg, wParam, lParam); }
相关参考:
1窗口创建:
http://www.oschina.net/code/snippet_146803_51275
2BMP文件读取:
http://blog.csdn.net/sun1956/article/details/8648460