数字图像处理实验三中值滤波和均值滤波实验报告
![数字图像处理实验三中值滤波和均值滤波实验报告](https://img.360docs.net/img00/17ordhzij08rt8867eej5x5l0gd04d-01.webp)
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
数字图像处理实验三中值滤波和均值滤波实验报告
数字图像处理实验三
均值滤波、中值滤波的计算机实现12281166 崔雪莹计科1202班
一、实验目的:
1)熟悉均值滤波、中值滤波处理的理论基础;
2)掌握均值滤波、中值滤波的计算机实现方法;
3)学习VC++ 6。0 的编程方法;
4)验证均值滤波、中值滤波处理理论;
5)观察均值滤波、中值滤波处理的结果。
二、实验的软、硬件平台:
硬件:微型图像处理系统,包括:主机, PC机;摄像机;
软件:操作系统:WINDOWS2000或WINDOWSXP应用软件:VC++ 6.0 三、实验内容:
1)握高级语言编程技术;
2)编制均值滤波、中值滤波处理程序的方法;
3)编译并生成可执行文件;
4)考察处理结果。
四、实验要求:
1)学习VC++确6。0 编程的步骤及流程;
2)编写均值滤波、中值滤波的程序;
3)编译并改错;
4)把该程序嵌入试验二给出的界面中(作适当修改);
5)提交程序及文档;
6)写出本次实验的体会。
五、实验结果截图
实验均值滤波采用的是3X3的方块,取周围的像素点取得其均值代替原像素点。边缘像素的处理方法是复制边缘的像素点,增加一个边框,计算里面的像素值得均值滤波。
六、实验体会
本次实验在前一次的实验基础上增加均值滤波和中值滤波,对于椒盐噪声的处理,发现中值滤波的效果更为好一点,而均值滤波是的整个图像变得模糊了一点,效果差异较大。本次实验更加增加了对数字图像处理的了解与学习。
七、实验程序代码注释及分析
// HistDemoADlg.h : 头文件
//
#include "ImageWnd.h"
#pragma once
// CHistDemoADlg 对话框
class CHistDemoADlg : public CDialogEx
{
// 构造
public:
CHistDemoADlg(CWnd* pParent = NULL); // 标准构造函数
int nWidth;
int nHeight;
int nLen;
int nByteWidth;
BYTE *lpBackup;
BYTE *lpBitmap;
BYTE *lpBits;
CString FileName;
CImageWnd source,dest;
// 对话框数据
enum { IDD = IDD_HISTDEMOA_DIALOG };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支
持
// 实现
protected:
HICON m_hIcon;
// 生成的消息映射函数
virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
DECLARE_MESSAGE_MAP()
public:
void LoadBitmap(void);
afx_msg void OnOpen();
afx_msg void OnHist();
void HistogramEq(void);
void NoColor(void);
void HistogramEq1(int nWidth,int nHeight,BYTE *lpInput,BYTE
*lpOutput);
void MeanFilter(int nWidth,int nHeight,BYTE *lpInput,BYTE
*lpOutput);
void MedianFilter(int nWidth,int nHeight,BYTE *lpInput,BYTE
*lpOutput);
afx_msg void OnBnClickedClose();
afx_msg void OnBnClickedMeanfilter();
afx_msg void OnBnClickedMedianfilter();
};
HistDemoADlg.cpp对HistDemoADlg.h进行具体的实现,OnOpen()函数响应ID为IDC_OPEN的按钮事件,而且会调取文件选择对话框,选取文件之后,会显
示在原始图像区域显示对应的位图图像,OnHist()函数会响应ID为
IDC_HIST的按钮事件,调用HistogramEq()进行直方图均衡化的处理,
HistogramEq()会调用HistogramEq1()进行直方图均衡化的处理,并用
dst.setImage()显示处理之后的图像,以及NoColor()函数,对原始图像转
化为灰度图像之后再显示。
// HistDemoADlg.cpp : 实现文件
//
#include "stdafx.h"
#include "HistDemoA.h"
#include "HistDemoADlg.h"
#include "afxdialogex.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
#define Point(x,y) lpPoints[(x)+(y)*nWidth]
#define Point1(x,y) lpPoints1[(x)+(y)*nWidth]
// 用于应用程序“关于”菜单项的 CAboutDlg 对话框
class CAboutDlg : public CDialogEx
{
public:
CAboutDlg();
// 对话框数据
enum { IDD = IDD_ABOUTBOX };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支
持
// 实现
protected:
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialogEx(CAboutDlg::IDD)
{
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
END_MESSAGE_MAP()
// CHistDemoADlg 对话框
CHistDemoADlg::CHistDemoADlg(CWnd* pParent /*=NULL*/)
: CDialogEx(CHistDemoADlg::IDD, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
lpBitmap = 0;
lpBackup = 0;
}
void CHistDemoADlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CHistDemoADlg, CDialogEx)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_OPEN, &CHistDemoADlg::OnOpen)
ON_BN_CLICKED(IDC_HIST, &CHistDemoADlg::OnHist)
ON_BN_CLICKED(IDCLOSE, &CHistDemoADlg::OnBnClickedClose)
ON_BN_CLICKED(IDC_MEANFILTER,
&CHistDemoADlg::OnBnClickedMeanfilter)
ON_BN_CLICKED(IDC_MEDIANFILTER,
&CHistDemoADlg::OnBnClickedMedianfilter)
END_MESSAGE_MAP()
// CHistDemoADlg 消息处理程序
BOOL CHistDemoADlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
// 将“关于...”菜单项添加到系统菜单中。
// IDM_ABOUTBOX 必须在系统命令范围内。
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
BOOL bNameValid;
CString strAboutMenu;
bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
ASSERT(bNameValid);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
// 执行此操作
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标
// TODO: 在此添加额外的初始化代码
source.Create(0,L"Source",WS_CHILD|WS_VISIBLE,CRect(40,40,360,28
0),this,10000);
dest.Create(0,L"Destination",WS_CHILD|WS_VISIBLE,CRect(400,40,72
0,280),this,10001);
return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}
void CHistDemoADlg::OnSysCommand(UINT nID, LPARAM lParam) {
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialogEx::OnSysCommand(nID, lParam);
}
}
// 如果向对话框添加最小化按钮,则需要下面的代码
// 来绘制该图标。对于使用文档/视图模型的 MFC 应用程序,// 这将由框架自动完成。
void CHistDemoADlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // 用于绘制的设备上下文
SendMessage(WM_ICONERASEBKGND,
reinterpret_cast
// 使图标在工作区矩形中居中
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// 绘制图标
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialogEx::OnPaint();
}
}
//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR CHistDemoADlg::OnQueryDragIcon()
{
return static_cast
}
void CHistDemoADlg::LoadBitmap()
{
//位图文件:BITMAPFILEHEADER+BITMAPINFOHEADER+有效信息部分
BITMAPINFOHEADER *pInfo; //位图文件的头部信息指针pInfo
pInfo=(BITMAPINFOHEADER *)(lpBitmap+sizeof(BITMAPFILEHEADER));
//pInfo指向位图文件的头部信息
nWidth=pInfo->biWidth; //图片宽度
nByteWidth=nWidth*3; //字节宽度
if (nByteWidth%4) nByteWidth+=4-(nByteWidth%4); //使字节宽度为4
的整数倍
nHeight=pInfo->biHeight; //图片高度
if (pInfo->biBitCount!=24) //位图的位深度不为24
{
if (pInfo->biBitCount!=8) //位深度不为8
{
AfxMessageBox(L"无效位图");
delete lpBitmap;
lpBitmap=0;
return;
}
//位深度为8
unsigned int PaletteSize=1<
PaletteSize调色板尺寸
if (pInfo->biClrUsed!=0 && pInfo->biClrUsed PaletteSize=pInfo->biClrUsed; // biClrUsed 位图实际使用的颜色表中 的颜色数 lpBits=lpBitmap+sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADE R);//lpBits指向有效信息部分 RGBQUAD *pPalette=(RGBQUAD *)lpBits; //颜色表部分 /* typedef struct tagRGBQUAD { BYTE rgbBlue; BYTE rgbGreen; BYTE rgbRed; BYTE rgbReserved; } RGBQUAD; */ lpBits+=sizeof(RGBQUAD)*PaletteSize;//lpBits指向图像有效信息部分 nLen=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+nByteWid th*nHeight;//整个位图文件的长度 BYTE *lpTemp=lpBitmap; lpBitmap=new BYTE[nLen]; BITMAPFILEHEADER bmh; BITMAPINFOHEADER bmi; bmh.bfType='B'+'M'*256; bmh.bfSize=nLen; bmh.bfReserved1=0; bmh.bfReserved2=0; bmh.bfOffBits=54; bmi.biSize=sizeof(BITMAPINFOHEADER); bmi.biWidth=nWidth; bmi.biHeight=nHeight; bmi.biPlanes=1; bmi.biBitCount=24; bmi.biCompression=BI_RGB; bmi.biSizeImage=0; bmi.biXPelsPerMeter=0; bmi.biYPelsPerMeter=0; bmi.biClrUsed=0; bmi.biClrImportant=0; int nBWidth=pInfo->biWidth; if (nBWidth%4) nBWidth+=4-(nBWidth%4); memset(lpBitmap,0,nLen); memcpy(lpBitmap,&bmh,sizeof(BITMAPFILEHEADER));//位图文件头部 memcpy(lpBitmap+sizeof(BITMAPFILEHEADER),&bmi,sizeof(BITMAPINFO HEADER));//位图信息头部 BYTE *lpBits2=lpBitmap+sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEAD ER);//位图图像信息部分 int x,y,p1,p2,Palette; for(y=0;y { for(x=0;x { p1=y*nBWidth+x; p2=y*nByteWidth+x*3; if (lpBits[p1] else Palette=0; lpBits2[p2]=pPalette[Palette].rgbBlue; lpBits2[p2+1]=pPalette[Palette].rgbGreen; lpBits2[p2+2]=pPalette[Palette].rgbRed; } } delete lpTemp; } lpBits=lpBitmap+sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER ); if (lpBackup) delete lpBackup; lpBackup=new BYTE[nLen]; memcpy(lpBackup,lpBitmap,nLen); } void CHistDemoADlg::OnOpen() //点击打开文件之后,对应的事件处理函数 { // TODO: 在此添加控件通知处理程序代码 CFile File; CFileDialog dlg(TRUE,0,0,OFN_HIDEREADONLY,L"位图文件|*.bmp|所有文 件|*.*||",this);//新建文件选择对话框 if (dlg.DoModal()==IDOK) { FileName=dlg.GetPathName(); //得到文件的路径 if (!File.Open(FileName,CFile::modeRead)) return; //以只读方式 打开文件 // TODO: add loading code here if (lpBitmap) delete lpBitmap; //保证lpBitmap为空 nLen=(int)File.GetLength(); //得到文件的长度 lpBitmap=new BYTE[nLen]; //为lpBitmap分配空间 File.Read(lpBitmap,nLen); //将文件的内容读入到lpBitmap所指 向的内存区域 LoadBitmap(); //调用LoadBitmap(),加载位图图像 if (lpBitmap) source.SetImage(nWidth,nHeight,lpBits); } } void CHistDemoADlg::OnHist() { // TODO: 在此添加控件通知处理程序代码 HistogramEq(); } void GetPoints(int nWidth,int nHeight,BYTE *lpBits,BYTE *lpPoints) { int x,y,p; int nByteWidth=nWidth*3; if (nByteWidth%4) nByteWidth+=4-(nByteWidth%4); for(y=0;y { for(x=0;x { p=x*3+y*nByteWidth; lpPoints[x+y*nWidth]=(BYTE)(0.299*(float)lpBits[p+2]+0.587*(flo at)lpBits[p+1]+0.114*(float)lpBits[p]+0.1); //三种颜色的比例计算 对应点的颜色值,并且强制转换成BYTE } } } void PutPoints(int nWidth,int nHeight,BYTE *lpBits,BYTE *lpPoints) //逐个对lpBits进行赋值 { int nByteWidth=nWidth*3; if (nByteWidth%4) nByteWidth+=4-(nByteWidth%4); int x,y,p,p1; for(y=0;y { for(x=0;x { p=x*3+y*nByteWidth; p1=x+y*nWidth; lpBits[p]=lpPoints[p1]; lpBits[p+1]=lpPoints[p1]; lpBits[p+2]=lpPoints[p1]; } } } void CHistDemoADlg::HistogramEq(void) { if (lpBitmap==0) return; BYTE *lpOutput=new BYTE[nByteWidth*nHeight]; HistogramEq1(nWidth,nHeight,lpBits,lpOutput); dest.SetImage(nWidth,nHeight,lpOutput); //在直方图均衡化的区域显 示结果 delete lpOutput; NoColor(); //将原始图像转换成灰度图像 } void CHistDemoADlg:: NoColor() { if (lpBitmap==0) return; int x,y,p; BYTE Point; for(y=0;y { for(x=0;x { p=x*3+y*nByteWidth; Point=(BYTE)(0.299*(float)lpBits[p+2]+0.587*(float)lpBits[p+1]+ 0.114*(float)lpBits[p]+0.1);//计算颜色值,在0-255的灰度级之间 lpBits[p+2]=Point; lpBits[p+1]=Point; lpBits[p]=Point; } } source.SetImage(nWidth,nHeight,lpBits);//将彩色图像转化成灰度图 像 } void CHistDemoADlg::HistogramEq1(int nWidth, int nHeight, BYTE *lpInput, BYTE *lpOutput) { int x,y; BYTE *lpPoints=new BYTE[nWidth*nHeight];//像素点的个数 GetPoints(nWidth,nHeight,lpInput,lpPoints); //lpPoints存的是颜色 值 int r[256],s[256]; //颜色值数组,统计对应颜色值像素点的个数 ZeroMemory(r,1024); ZeroMemory(s,1024); for(y=0;y 是lpPoints(x,y) for(x=0;x r[Point(x,y)]++; } } s[0]=r[0]; for(y=1;y<256;y++) { s[y]=s[y-1]; s[y]+=r[y]; } //计算颜色值的前y种颜色的总像素点的个数(像素点颜色值<=y) for(y=0;y 结果保存在lpPoints for(x=0;x Point(x,y)=s[Point(x,y)]*255/nWidth/nHeight; } } PutPoints(nWidth,nHeight,lpOutput,lpPoints); //输出lpPoints到 lpOutput delete lpPoints; } void CHistDemoADlg::OnBnClickedClose() { // TODO: 在此添加控件通知处理程序代码 //ExitProcess(0);//注意使用时先释放分配的内存,以免造成内存泄露 //exit(0) ;//正常终止程序; exit(非0)非正常终止程序 PostQuitMessage(0);//最常用 } void CHistDemoADlg::OnBnClickedMeanfilter() { // TODO: 在此添加控件通知处理程序代码 if (lpBitmap==0) return; BYTE *lpOutput=new BYTE[nByteWidth*nHeight]; MeanFilter(nWidth,nHeight,lpBits,lpOutput); dest.SetImage(nWidth,nHeight,lpOutput); //在直方图均衡化的区域显 示结果 delete lpOutput; NoColor(); //将原始图像转换成灰度图像 } void CHistDemoADlg::MeanFilter (int nWidth,int nHeight,BYTE *lpInput,BYTE *lpOutput) { int x,y; BYTE *lpPoints=new BYTE[nWidth*nHeight];//像素点的个数 BYTE *lpPoints1 = new BYTE[(nWidth+2)*(nHeight+2)]; GetPoints(nWidth,nHeight,lpInput,lpPoints); //lpPoints存的是颜色值 for(y=1;y for(x=1;x Point1(x,y) = Point(x-1,y-1); //lpPoints1[y][x] = lpPoints[y-1][x-1]; } } for(y=1;y Point1(0,y) = Point(0,y-1); Point1(nWidth+1,y) = Point(nWidth-1,y-1); //lpPoints1[y][0] = lpPoints[y-1][0]; //lpPoints1[y][nWidth+1] = lpPoints[y-1][nWidth-1]; } for(x=0;x Point1(x,0) = Point1(x,1); Point1(x,nHeight+1) = Point1(x,nHeight); //lpPoints1[0][x] = lpPoints1[1][x]; //lpPoints1[nHeight+1][x] = lpPoints1[nHeight][x]; } for(y=0;y for (x=0;x Point(x,y) = ( Point1(x,y) + Point1(x+1,y) + Point1(x+2,y) + Point1(x,y+1) + Point1(x+1,y+1) + Point1(x+2,y+1) + Point1(x,y+2) + Point1(x+1,y+2) + Point1(x+2,y+2) )/9; /* lpPoints[y][x] = (lpPoints1[y][x] + lpPoints1[y][x+1] + lpPoints1[y][x+2] + lpPoints1[y+1][x] + lpPoints1[y+1][x+1] + lpPoints1[y+1][x+2] + lpPoints1[y+2][x] + lpPoints1[y+2][x+1] + lpPoints1[y+2][x+2])/9; */ } } PutPoints(nWidth,nHeight,lpOutput,lpPoints); //输出lpPoints到 lpOutput delete lpPoints; } void CHistDemoADlg::MedianFilter(int nWidth,int nHeight,BYTE *lpInput,BYTE *lpOutput) { int x,y; BYTE *lpPoints=new BYTE[nWidth*nHeight];//像素点的个数 BYTE *lpPoints1 = new BYTE[(nWidth+2)*(nHeight+2)]; GetPoints(nWidth,nHeight,lpInput,lpPoints); //lpPoints存的是颜色 值 for(y=1;y for(x=1;x Point1(x,y) = Point(x-1,y-1); } } for(y=1;y Point1(0,y) = Point(0,y-1); Point1(nWidth+1,y) = Point(nWidth-1,y-1); } for(x=0;x Point1(x,0) = Point1(x,1); Point1(x,nHeight+1) = Point1(x,nHeight); } BYTE *window = new BYTE[9]; for(y=0;y for (x=0;x int k = 0; for(int i=y ; i <= y+2 ; i++){ for(int j=x ; j <= x+2; j++){ if(k < 9) window[k++] = Point1(j,i); } } for (int m = 0; m < 5; ++m) //求9个数的中值,window[4]为中值 { int min = m; for (int n = m + 1; n < 9; ++n) if (window[n] < window[min]) min = n; // Put found minimum element in its place BYTE temp = window[m]; window[m] = window[min]; window[min] = temp; } Point(x,y) = window[4]; } } PutPoints(nWidth,nHeight,lpOutput,lpPoints); //输出lpPoints到 lpOutput delete lpPoints; } void CHistDemoADlg::OnBnClickedMedianfilter() { // TODO: 在此添加控件通知处理程序代码 if (lpBitmap==0) return; BYTE *lpOutput=new BYTE[nByteWidth*nHeight]; MedianFilter(nWidth,nHeight,lpBits,lpOutput); dest.SetImage(nWidth,nHeight,lpOutput); //在中值滤波的区域显示结 果 delete lpOutput; NoColor(); //将原始图像转换成灰度图像 } CImageWnd.h类继承自CWnd主要是图像显示方面的函数,如水平滚轮和垂直滚轮的事件函数,以及绘制函数OnPaint(),初始化函数等等,以及存放需要绘制的 图像信息的成员变量。setImage(),外接提供绘制的信息,通过参数传递 给内部的成员变量。 #pragma once class CImageWnd:public CWnd public: int HCurrentPosition; //当前位置(水平) int HScrollMax; //滑动最大位置(水平) int HScrollPosition; //滑动位置(水平) int VCurrentPosition; //当前位置(垂直) int VScrollMax; //滑动最大位置(垂直) int VScrollPosition; //滑动位置(垂直) int nWidth; //宽度 int nHeight; //高度 int nByteWidth; //字节宽度 BYTE *lpBits; //指向字节的指针 public: CImageWnd(void); ~CImageWnd(void); void SetImage(int cx,int cy,const void *bits); void SetScroll(int cx,int cy); protected: afx_msg BOOL OnEraseBkgnd(CDC *pDC); afx_msg void OnHScroll(UINT nSBCode,UINT nPos,CScrollBar *pScrollBar); afx_msg void OnVScroll(UINT nSBCode,UINT nPos,CScrollBar *pScrollBar); afx_msg void OnPaint(); afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); DECLARE_MESSAGE_MAP() /* protected: //{{AFX_MSG(CImageWnd) afx_msg BOOL OnEraseBkgnd(CDC* pDC); afx_msg void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar); afx_msg void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar); afx_msg void OnPaint(); afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); //}}AFX_MSG DECLARE_MESSAGE_MAP() */ }; ImageWnd.cpp 具体实现ImageWnd.h的一些功能函数,注释已经给出,在此不再赘述。#include "StdAfx.h" #include "ImageWnd.h" #define BACKGROUND RGB(128,128,128) CImageWnd::CImageWnd(void) //初始化,将其全设为0 { HScrollPosition = 0; HCurrentPosition = 0; HScrollMax = 0; VScrollPosition = 0; VCurrentPosition = 0; VScrollMax = 0; lpBits = 0; } CImageWnd::~CImageWnd(void) //析构函数,释放空间 { if(lpBits) delete lpBits; } BEGIN_MESSAGE_MAP(CImageWnd, CWnd) //{{AFX_MSG_MAP(CImageWnd) ON_WM_ERASEBKGND() ON_WM_HSCROLL() ON_WM_VSCROLL() ON_WM_PAINT() ON_WM_CREATE() //}}AFX_MSG_MAP END_MESSAGE_MAP() BOOL CImageWnd::OnEraseBkgnd(CDC *pDC) //设置背景色,320,240 { if(!lpBits) pDC->FillSolidRect(0,0,320,240,BACKGROUND); return TRUE; } void CImageWnd::OnPaint() //绘制函数,每次需要显示的图像发生变化,就会重画,重复调用这个函数进行重画