//
#include
#include
#include
#include
#include
#include
#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
//这里比较关键了,
//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