2009年 7月 24日 数字图象处理演示稿 纪玉波制作
(C)
1
使用 VC++建立程序的过程
1,点击 VC++图标进入;
2,点击菜单中的,文件,,在出现的下拉菜单中点击,新建,;
3,在弹出的菜单中点击,工程,;
4,在工程栏目点,Win32 Application”,然后在右边,工程,框中填上一个自定的程序名,按底部的,确定,;
5,在下一个画面中选择,A typical
“Hello World!” application”,然后点击底部的,完成,;
6,对下一个画面中选择,确定,;
7,回到 VC++主页面后选择打开文件,调入自定名称以 cpp为后缀的文件,进行修改 。
2009年 7月 24日 数字图象处理演示稿 纪玉波制作
(C)
2
// 图像处理程序示例,cpp
#include "stdafx.h"
#include "resource.h"
//添加下面的头文件
#include <stdio.h>
#define MAX_LOADSTRING 100
// Global Variables:
HINSTANCE hInst; // current instance
TCHAR szTitle[MAX_LOADSTRING]; // The title bar text
TCHAR szWindowClass[MAX_LOADSTRING]; // The title bar text
// Foward declarations of functions included in this code module:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE,int);
LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
LRESULT CALLBACK About(HWND,UINT,WPARAM,LPARAM);
2009年 7月 24日 数字图象处理演示稿 纪玉波制作
(C)
3
//此处添加图像处理程序说明
void ImageProcessing(HWND hWnd);
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
// TODO,Place code here.
MSG msg;
HACCEL hAccelTable;
// Initialize global strings
LoadString(hInstance,IDS_APP_TITLE,szTitle,MAX_LOADSTRING);
LoadString(hInstance,IDC_MY,szWindowClass,MAX_LOADSTRING);
MyRegisterClass(hInstance);
// Perform application initialization:
if (!InitInstance (hInstance,nCmdShow))
{
return FALSE;
}
2009年 7月 24日 数字图象处理演示稿 纪玉波制作
(C)
4
hAccelTable = LoadAccelerators(hInstance,(LPCTSTR)IDC_MY);
// Main message loop:
while (GetMessage(&msg,NULL,0,0))
{
if (!TranslateAccelerator(msg.hwnd,hAccelTable,&msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return msg.wParam;
}
2009年 7月 24日 数字图象处理演示稿 纪玉波制作
(C)
5
// FUNCTION,MyRegisterClass()
// PURPOSE,Registers the window class.
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = (WNDPROC)WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance,(LPCTSTR)IDI_MY);
wcex.hCursor = LoadCursor(NULL,IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = (LPCSTR)IDC_MY;
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance,(LPCTSTR)IDI_SMALL);
return RegisterClassEx(&wcex);
}
2009年 7月 24日 数字图象处理演示稿 纪玉波制作
(C)
6
// FUNCTION,InitInstance(HANDLE,int)
// PURPOSE,Saves instance handle and creates main 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;
}
2009年 7月 24日 数字图象处理演示稿 纪玉波制作
(C)
7
// FUNCTION,WndProc(HWND,unsigned,WORD,LONG)
// PURPOSE,Processes messages for the main window.
LRESULT CALLBACK WndProc(HWND hWnd,UINT message,WPARAM wParam,
LPARAM lParam)
{
int wmId,wmEvent;
PAINTSTRUCT ps;
HDC hdc;
TCHAR szHello[MAX_LOADSTRING];
LoadString(hInst,IDS_HELLO,szHello,MAX_LOADSTRING);
switch (message)
{
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// Parse the menu selections:
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst,(LPCTSTR)IDD_ABOUTBOX,hWnd,(DLGPROC)About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
2009年 7月 24日 数字图象处理演示稿 纪玉波制作
(C)
8
default:
return DefWindowProc(hWnd,message,wParam,lParam);
}
break;
case WM_PAINT:
hdc = BeginPaint(hWnd,&ps);
// TODO,Add any drawing code here...
RECT rt;
GetClientRect(hWnd,&rt);
//此处调用图像处理程序
ImageProcessing(hWnd);
//将下面一句屏蔽掉
// DrawText(hdc,szHello,strlen(szHello),&rt,DT_CENTER);
EndPaint(hWnd,&ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd,message,wParam,lParam);
}
return 0;
}
2009年 7月 24日 数字图象处理演示稿 纪玉波制作
(C)
9
// Mesage handler for about box.
LRESULT CALLBACK About(HWND hDlg,UINT message,WPARAM wParam,LPARAM
lParam)
{
switch (message)
{
case WM_INITDIALOG:
return TRUE;
case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg,LOWORD(wParam));
return TRUE;
}
break;
}
return FALSE;
}
2009年 7月 24日 数字图象处理演示稿 纪玉波制作
(C)
10
// 图像处理程序
void ImageProcessing(HWND hWnd)
{
//定义程序中使用的变量
#define WIDTHBYTES(i)((i+31)/32*4)
HFILE hf;
LPBITMAPINFOHEADER lpImgData;
LOGPALETTE *pPal;
LPRGBQUAD lpRGB;
HPALETTE hPrevPalette;
HPALETTE hPalette=NULL;
HDC hDc;
HLOCAL hPal;
DWORD ImgWidth,ImgHeight,LineBytes,ImgSize;
COLORREF color=(0,0,0);
DWORD i;
BITMAPFILEHEADER bf;
BITMAPINFOHEADER bi;
HBITMAP hBitmap;
HGLOBAL hImgData=NULL;
HDC hdcmem=NULL;
DWORD NumColors=0;
char *BmpFileName;
2009年 7月 24日 数字图象处理演示稿 纪玉波制作
(C)
11
//说明图像具体处理的子程序
void ShowImage(HDC,DWORD,DWORD,HDC);
//读入图像文件
BmpFileName="miss.bmp";
hf=_lopen(BmpFileName,OF_READ);
//读出图像文件的文件头和信息头
_lread(hf,(LPSTR)&bf,sizeof(BITMAPFILEHEADER));
_lread(hf,(LPSTR)&bi,sizeof(BITMAPINFOHEADER));
//得到图像的宽度和高度
ImgWidth=bi.biWidth;
ImgHeight=bi.biHeight;
//得到图像每行的字节数。每行字节数为 4的整倍数,否则补 0
LineBytes=(DWORD)WIDTHBYTES(bi.biWidth*bi.biBitCount);
//计算图像数据总字节数
ImgSize=(DWORD)LineBytes*bi.biHeight;
2009年 7月 24日 数字图象处理演示稿 纪玉波制作
(C)
12
//得到图像颜色数
switch(bi.biBitCount)
{
case 1:
NumColors=2;
break;
case 4:
NumColors=16;
break;
case 8:
NumColors=256;
break;
case 24:
NumColors=0;
break;
default:
return;
}
2009年 7月 24日 数字图象处理演示稿 纪玉波制作
(C)
13
//计算图像文件总字节数
bf.bfSize=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+NumColors
*sizeof(RGBQUAD) + ImgSize;
//信息头、调色板和图像数据分配内存
if((hImgData=GlobalAlloc(GHND,(DWORD)(sizeof(BITMAPINFOHEADER)+
NumColors*sizeof(RGBQUAD)+ImgSize)))==NULL)
{
_lclose(hf);
return;
}
//为读取颜色数据及图像数据做准备
lpImgData=(LPBITMAPINFOHEADER)GlobalLock(hImgData);
_llseek(hf,sizeof(BITMAPFILEHEADER),SEEK_SET);
_hread(hf,(char *)lpImgData,(long)sizeof(BITMAPINFOHEADER)
+(long)NumColors*sizeof(RGBQUAD)+ImgSize);
_lclose(hf);
2009年 7月 24日 数字图象处理演示稿 纪玉波制作
(C)
14
//获得颜色数据
if(NumColors!=0)
{
hPal=LocalAlloc(LHND,sizeof(LOGPALETTE) + NumColors* sizeof(PALETTEENTRY));
pPal =(LOGPALETTE *)LocalLock(hPal);
pPal->palNumEntries =(WORD) NumColors;
pPal->palVersion = 0x300;
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++;
}
hPalette=CreatePalette(pPal);
LocalUnlock(hPal);
LocalFree(hPal);
}
2009年 7月 24日 数字图象处理演示稿 纪玉波制作
(C)
15
//使用当前的窗口
hDc=GetDC(hWnd);
if(hPalette)
{
//从当前逻辑调色板中映射调色板入口点到系统调色板中
hPrevPalette=SelectPalette(hDc,hPalette,FALSE);
SelectPalette (hdcmem,hPalette,FALSE);
RealizePalette(hDc);
}
// 创建设备无关位图
hBitmap=CreateDIBitmap(hDc,(LPBITMAPINFOHEADER)lpImgData,(LONG)CBM_INIT,
(LPSTR)lpImgData+sizeof(BITMAPINFOHEADER) +NumColors*sizeof(RGBQUAD),
(LPBITMAPINFO)lpImgData,DIB_RGB_COLORS);
//为读取图像数据准备
hdcmem=CreateCompatibleDC(hDc);
SelectObject(hdcmem,hBitmap);
SetStretchBltMode(hDc,STRETCH_DELETESCANS);
//调用图像处理子程序
ShowImage(hDc,ImgWidth,ImgHeight,hdcmem);
//释放窗口和数据区
ReleaseDC(hWnd,hDc);
GlobalUnlock(hImgData);
return;
}
2009年 7月 24日 数字图象处理演示稿 纪玉波制作
(C)
16
void ShowImage(HDC hDc,DWORD ImgWidth,DWORD ImgHeight,HDC hdcmem)
{
//原始图像显示
DWORD i,j;
COLORREF color;
for(i=0;i<ImgWidth;i++)
for(j=0;j<ImgHeight;j++)
{
color=GetPixel(hdcmem,i,j);
SetPixelV(hDc,i,j,color);
}
}