@convey srl.it 是什么邮箱

基于MFC对话框的OpenGL三维图形开发
以三维动态球体模型来讲述基于MFC对话框的OpenGL编程
1.基本思想
在Windows98/NT平台下,GDI是原始窗口的图形接口。而GDI实现这些是通过一个设备描述表DC来实现的。现在通过OpenGL绘图需要创建绘图描述表RC。但是RC并不能直接完成绘图,只能与特定的DC联系起来,从而完成具体的绘图工作。最后要注意释放RC和DC。
& 2. 编程步骤
第一步,设置开发环境
现在以Windows2000为例,首先将glu.dll,glu32.dll,glut.dll,glut32.dll,opengl32.dll文件拷贝到操作系统WINNT/System32目录下,将gl.h,glaux.h,glu.h,glut.h拷贝到Microsoft
Studio/VC98/Include/GL目录中中,将glaux.lib,glu32.lib,glut32.lib,opengl32.lib拷贝到Microsoft
Studio/VC98/Lib目录中;然后在编译程序的时候选择Project|Setting菜单,在Link标签中的Object/library
modules编辑框中输入“opengl32.lib, glut32.lib
,glu32.lib,glaux.lib”。到这时候环境就建立好了,可以进行下面的具体编程工作。
第二步,具体编程
本实例采用基于对话框的工程。至于用单文档方式和多文档方式其编程原理是一样的,这里不再作单独介绍。
2.1创建项目文件。选择File|New菜单项,新建一个基于对话框的项目文件MyDlgOpenGL;
2.2 修改对话框模板。删除对话框中的静态文本,调整控件的位置。
2.3 创建新类,添加消息映射。选择View|ClassWizard菜单项,打开MFC对话框,在Add
Class之中选择New,以便添加一个新类COpenGL,且该类的基类选择generic CWnd;最后利用MFC
ClassWizard为COpenGL类添加消息WM_CREATE,WM_PAINT的映射。
2.4 添加代码。
& 2.4.1 定义像素格式 ,创建OpenGL显示。
在OpenGL能够在一个绘图对象中绘图之前,该绘图对象必须初始化。为此引入像素格式的概念。像素格式能告诉OpenGL是否使用双缓存,颜色模式,颜色位数,深度位数等等重要信息。
它由一个被称作PIXELFORMATDESCRIPTOR的所描述。于是定义在OpenGL.h中定义函数int
MySetPixelFormat(HDC hdc)。然后在OpenGL.cpp文件中加入如下代码:
int COpenGL::MySetPixelFormat(HDC hdc)
PIXELFORMATDESCRIPTOR pfd = {
sizeof(PIXELFORMATDESCRIPTOR),&&
// pfd结构的大小
1,&&&&&&&&&&&&&&&&&&&&&&&&&&&&
PFD_DRAW_TO_WINDOW
|&&&&&&&&&&&
// 支持在窗口中绘图
PFD_SUPPORT_OPENGL
|&&&&&&&&&&&&&
// 支持 OpenGL
PFD_DOUBLEBUFFER,&&&&&&&&&&&&&
// 双缓存模式
PFD_TYPE_RGBA,&&&&&&&&&&&&&&&&&
// RGBA 颜色模式
24,&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
// 24 位颜色深度
&&& 0, 0, 0, 0,
0,&&&&&&&&&&&&&&&&&&&&&&&&
// 忽略颜色位
0,&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
// 没有非透明度缓存
0,&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
// 忽略移位位
0,&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
// 无累计缓存
&&& 0, 0, 0,
0,&&&&&&&&&&&&&
&&&&&&&&&&&&&&&//
忽略累计位
32,&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
位深度缓存&&&&
0,&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
// 无模板缓存
0,&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
// 无辅助缓存
PFD_MAIN_PLANE,&&&&&&&&&&&&&&&&&&
0,&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&&//
0&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
// 忽略层,可见性和损毁掩模
int& iPixelF
为设备描述表得到最匹配的像素格式
if((iPixelFormat = ChoosePixelFormat(hdc, &pfd)) == 0)
MessageBox("ChoosePixelFormat Failed", NULL, MB_OK);
设置最匹配的像素格式为当前的像素格式
if(SetPixelFormat(hdc, iPixelFormat, &pfd) == FALSE)
MessageBox("SetPixelFormat Failed", NULL, MB_OK);
&&& return
现在就可以在OnCreate函数中创建绘图描述表。其代码如下:
int COpenGL::OnCreate(LPCREATESTRUCT lpCreateStruct)
(CWnd::OnCreate(lpCreateStruct) == -1)
return -1;
MySetPixelFormat(::GetDC(m_hWnd));&&&&&&
// 设置当前的绘图像素格式
::GetDC(m_hWnd);&&&&&&&&&&&&&&&&&
// 获得绘图描述表
&&& hglrc =
wglCreateContext(hdc);&&&&&&&&&&&&&
// 创建绘图描述表
wglMakeCurrent(hdc, hglrc);
&&&&&&&&&&&&&&//
使绘图描述表为当前调用现程的当前绘图描述表
&&& return
进行光照处理,添加OpenGL显示。
在OpenGL.h中定义函数LightShine函数,作为添加光源和材质属性的函数。在该函数中将创建两个光源,并使其位于不同位置,以产生不同的效果。定义:环境光,散射光,镜面光和镜面反射指数。因为没有一种光源完全由以上三种中的一种光源组成,所以任何一种光源都是由以上三种光源的光照成分组成的,即为混合光源。其成分值由RGBA定义。用材料对光的三原色的反射率来定义材料的颜色,与光源相对应,。代码如下:
void COpenGL::LightShine(void)
GLfloat mat_diffuse[4]={1,0.5,0.5,1.0};
GLfloat mat_specular[4]={1.0,1.0,1.0,1.0};
GLfloat mat_shininess[1]={100.0};
&&& //光源
GLfloat light_position0[4]={0,500,500,0};
glMaterialfv(GL_FRONT,GL_DIFFUSE,mat_diffuse);
glMaterialfv(GL_FRONT,GL_SPECULAR,mat_specular);
glMaterialfv(GL_FRONT,GL_SHININESS,mat_shininess);
glLightfv(GL_LIGHT0,GL_POSITION,light_position0);
glEnable(GL_LIGHT0);
//光源 2&&&
GLfloat light_position1[4]={,1000,0};
GLfloat mat_diffuse1[4]={0.5,0.5,1.0,1.0};
glLightfv(GL_LIGHT1,GL_DIFFUSE,mat_diffuse1);
glLightfv(GL_LIGHT1,GL_SPECULAR,mat_specular);
glLightfv(GL_LIGHT1,GL_SHININESS,mat_shininess);
glLightfv(GL_LIGHT1,GL_POSITION,light_position1);
glEnable(GL_LIGHT1);
//使模型能接受光照
glEnable(GL_LIGHTING);&
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE,GL_TRUE);
glDepthFunc(GL_LESS);
glEnable(GL_DEPTH_TEST);
//计算定点法线
glEnable(GL_AUTO_NORMAL);
glEnable(GL_NORMALIZE);
2.4.3 定义绘图窗口
所绘球体在哪个区域内进行绘制以及这个区域的风格是怎样的必须需要进行定义。为下一步的绘图工作打下基础。那么可以在MyDlgOpenGLDlg.cpp的函数OnInitDialog()中加入如下代码:
CRect rect(7, 7, 300,
300);&&&&&&&&&&&&&&&&&
//定义绘图区域的大小
&& m_pDisplay-&Create(
&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
//定义窗口风格
&&&&&&&&&&&&&&&&
WS_CHILD|WS_CLIPSIBLINGS|WS_CLIPCHILDREN|WS_VISIBLE,
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
2.4.4 绘制图象
在前面的准备之后,现在可以在OnPaint函数中绘制图象。在具体进行绘制物体时,需要注意的是:glPushMatrix()与glPopMatrix()的使用必须成对出现。此外,必须正确使用glScale()
函数和glRatate() 函数以及双缓存技术,以实现所绘球体的在指定窗口由远及近,由小变大的旋转。代码如下:
void COpenGL::OnPaint()
&&&&&&&&&&&&&&&&
&& glClear(GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT);&
& space+=0.005;
& if(space&1.0)
space=0.1;
&& step = step + 1.0;
&if (step & 360.0)
step = step - 360.0;
& glPushMatrix();
glScalef(space,space,space);
& glRotatef(step,0.0,1.0,0.0);
& glRotatef(step,0.0,0.0,1.0);
& glRotatef(step,1.0,0.0,0.0);
LightShine();&&&&&&&&&&&&&&&&&&&&&&&&&&&&
//添加光照属性
glutSolidSphere(1.0,20,16);&&&&&&&&&&&&&&&&&
//绘制球体
& glPopMatrix();
& glFlush();
SwapBuffers(hdc);&&&&&&&&&&&&&&&&&&&&&&&&
//使用双缓存技术实现交换缓冲区
2.4.5 结束运行
在结束运行时,我们必须将一些环境变量释放。于是应该在添加的类COpenGL的析构函数中进行操作,以释放DC和删除RC。代码如下:
COpenGL::~COpenGL()
&& wglMakeCurrent(NULL, NULL)
&&&&&&&&&&&&&&
wglDeleteContext(hglrc);&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
//删除绘图描述表
&& ::ReleaseDC (m_hWnd, hdc) ;
&&&&&&&&&&&&&&//释放设备描述表
利用Visual
C++强大的窗口功能完成了OpenGL绘制球体的程序的编制工作,上述程序运行正常,其结果是一个动态的球体。理解了上述编程过程,就可以使我们自如地运用MFC进行其他的OpenGL编程。
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。数字图像处理四.MFC对话框绘制灰度直方图
& & & & 本文主要讲述基于VC++6.0 MFC图像处理的应用知识,主要结合自己大三所学课程《数字图像处理》及课件进行回忆讲解,主要通过MFC单文档视图实现点击弹出对话框绘制BMP图片的灰度直方图,再获取平均灰度、中指灰度和标准差等值。文章比较详细基础,希望该篇文章对你有所帮助~
& & & &一.MFC详解显示BMP格式图片
& & & &二.MFC单文档分割窗口显示图片
& & & &三.MFC实现图像灰度、采样和量化功能详解
& & & &&免费资源下载地址:
& & & &&http://download.csdn.net/detail/eastmount/8757243
一. 程序运行结果
& & & & 该篇文章主要是在上一篇文章基础上进行的讲解,其中当打开一张BMP图像后,点击”直方图“-》”显示原图直方图“如下。
二. 灰度直方图原理
& & & & 什么是灰度直方图?
& & & & 灰度直方图(histogram)是灰度级的函数,描述的是图像中每种灰度级像素的个数,反映图像中每种灰度出现的频率。横坐标是灰度级,纵坐标是灰度级出现的频率。
& & & &&对于连续图像,平滑地从中心的高灰度级变化到边缘的低灰度级。直方图定义为:
& & & &&其中A(D)为阈值面积函数:为一幅连续图像中被具有灰度级D的所有轮廓线所包围的面积。对于离散函数,固定ΔD为1,则:H(D)=A(D)-A(D+1)
& & & &&色彩直方图是高维直方图的特例,它统计色彩的出现频率,即色彩概率分布信息。
& & & &&通常这需要一定的量化过程,将色彩分成若干互不重叠的种类。一般不直接在RGB色彩空间中统计,而是在将亮度分离出来后,对代表色彩部分的信息进行统计,如在HSI空间的HS子空间、YUV空间的UV子空间,以及其它反映人类视觉特点的彩色空间表示中进行。
& & & & 其中直方图的计算方法如下:
& & & &&依据定义,若图像具有L(通常L=256,即8位灰度级)级灰度,则大小为MxN的灰度图像f(x,y)的灰度直方图hist[0…L-1]可用如下计算获得。
& & & & 1、初始化 hist[k]=0; k=0,…,L-1&
& & & & 2、统计 hist[f(x,y)]++; x=0,…,M-1, y =0,…,N-1&
& & & & 3、归一化 hist[f(x,y)]/=M*N&
& & & & 那么说了这么多,直方图究竟有什么作用呢?
& & & & 在使用轮廓线确定物体边界时,通过直方图更好的选择边界阈值,进行阈值化处理;对物体与背景有较强对比的景物的分割特别有用;简单物体的面积和综合光密度IOD可以通过图像的直方图求得。
三. 程序实现
1.建立直方图对话框
& & & &第一步:创建Dialog
& & & & 将视图切换到ResourceView界面,选中Dialog右键鼠标新建一个Dialog,并新建一个名为IDD_DIALOG_ZFT,设置成下图对话框。
& & & & 右键添加属性如下:
& & & & 对话框-原始直方图-IDD_DIALOG_ZFT
& & & & 组框-RGB-IDC_STATIC_RGB
& & & & 图像-框架-IDC_STATIC_KJ-蚀刻(重点:有它才能添加直方图在此处,注意GetDlgItem()函数中是IDC而不是IDD对话框)
& & & & 添加蚀刻线(图像蚀刻形成的直线)形如图中的3个矩形框,并添加静态文本:Red、Green、Blue、红、绿、蓝、像素、平均灰度、中值灰度、标准差;这些静态文本都是IDC_STATIC且为默认属性
& & & & 添加红色4个值(Static)、绿色4个值、蓝色4个值,分别为:
& & & & IDC_STATIC_XS_RED(GREEN BLUE)对应像素XS
& & & & IDC_STATIC_PJHD_RED(GREEN BLUE)对应平均灰度PJHD
& & & & IDC_STATIC_ZZHD_RED(GREED BLUE)对应中值灰度ZZHD
& & & & IDC_STATIC_BZC_RED(GREEN BLUE)对应标准差BZC
& & & &第二步:建立类向导MFC ClassWizard
& & & & (1) 在对话框资源模板空白区双击鼠标(Ctrl+W),创建一个新类,命名为CImageZFTDlg会自动生成它的.h和.cpp文件。在类向导中选中类名CImageZFTDlg,IDs为CImageZFTDlg,WM_INITDIALOG建立这个函数用于初始化。
& & & & (2) 打开类向导,选择Member Variables页面,添加如下变量,类型均为CString。
& & & & 像素 m_redXS、m_greenXS、m_blueXS
& & & & 标准差 m_redBZC、m_greeenBZC、m_blueBZC
& & & & 平均灰度 m_redPJHD、m_greenPJHD、m_bluePJHD
& & & & 中值灰度 m_redZZHD、m_greenZZHD、m_blueZZHD
& & & & (3) 在View.cpp中添加直方图的头文件 #inlcude &ImageZFTDlg.h&
& & & & 第三步:设置菜单栏调用直方图对话框
& & & & (1) 将视图切换到ResourceView界面,选中Menu,在IDR_MAINFRAM中添加菜单项“直方图”,菜单属性中选择“弹出”,在“直方图”中添加子菜单“显示原图直方图”。
& & & & (2) 设置其属性为ID_ZFT_YT(显示直方图原图),同时建立类向导,选择ID_ZFT_YT(IDs),通过COMMAND建立显示直方图函数OnZftYt()。
& & & &第四步:添加代码及计算4个值
& & & & 在ImageProcessingView.cpp中添加如下代码,注释中有如何求平均灰度、中值灰度和标准差的消息算法过程。
//引用显示直方图头文件
#include &ImageZFTDlg.h&
#include &math.h&
/*全局变量在TestZFTDlg.cpp中引用 用extern*/
int Red[256],Green[256],Blue[256];
/* 添加直方图显示功能,并在直方图下方显示相关信息
/* 如平均灰度、中值灰度、标准差和像素总数
/* ID_ZFT_YT:直方图原图显示
void CImageProcessingView::OnZftYt()
if(numPicture==0) {
AfxMessageBox(&载入图片后才能显示原图直方图!&,MB_OK,0);
AfxMessageBox(&显示原图直方图!&,MB_OK,0);
CImageZFTD
//打开临时的图片
FILE *fpo = fopen(BmpName,&rb&);
fread(&bfh,sizeof(BITMAPFILEHEADER),1,fpo);
fread(&bih,sizeof(BITMAPINFOHEADER),1,fpo);
for(j=0;j&256;j++) { //定义数组并清零
Green[j]=0;
Blue[j]=0;
//计算4个数据
unsigned char red,green,
int IntRed,IntGreen,IntB
//强制转换
double sumRedHD=0,sumGreenHD=0,sumBlueHD=0;
//记录像素总的灰度值和
for(i=0; i&m_nImage/3; i++ )
fread(&red,sizeof(char),1,fpo);
IntRed=int(red);
sumRedHD=sumRedHD+IntR
if( IntRed&=0 && IntRed&256 ) Red[IntRed]++; //像素0-255之间
fread(&green,sizeof(char),1,fpo);
IntGreen=int(green);
sumGreenHD=sumGreenHD+IntG
if( IntGreen&=0 && IntGreen&256 ) Green[IntGreen]++;
fread(&blue,sizeof(char),1,fpo);
IntBlue=int(blue);
sumBlueHD=sumBlueHD+IntB
if( IntBlue&=0 && IntBlue&256 ) Blue[IntBlue]++;
fclose(fpo);
//像素:int型转换为CString型
dlg.m_redXS.Format(&%d&,m_nImage);
dlg.m_greenXS.Format(&%d&,m_nImage);
dlg.m_blueXS.Format(&%d&,m_nImage);
//平均灰度值:计算24位bmp图片的灰度值,我是记录RGB中的所有平均值
float pinRedHD,pinGreenHD,pinBlueHD;
pinRedHD=sumRedHD*3/m_nI
pinGreenHD=sumGreenHD*3/m_nI
//平均灰度=总灰度/总像素
pinBlueHD=sumBlueHD*3/m_nI
dlg.m_redPJHD.Format(&%.2f&,pinRedHD);
dlg.m_greenPJHD.Format(&%.2f&,pinGreenHD);
dlg.m_bluePJHD.Format(&%.2f&,pinBlueHD);
/* 中值灰度:算法重点(黄凯大神提供)
/* 中值灰度:所有像素中的中位数,应该所有像素排序找到中间的灰度值
/* 算法:num[256]记录各灰度出现次数,sum+=num[i],找到sum=总像素/2
int sumRedZZHD=0,sumGreenZZHD=0,sumBlueZZHD=0;
int redZZHD,greenZZHD,blueZZHD;
for(i=0;i&256;i++)
sumRedZZHD=sumRedZZHD+Red[i];
if(sumRedZZHD&=m_nImage/6)
//m_nImage被分成3份RGB并且sum=总像素/2
redZZHD=i;
for(i=0;i&256;i++)
sumGreenZZHD=sumGreenZZHD+Green[i];
if(sumGreenZZHD&=m_nImage/6)
//m_nImage被分成3份RGB并且sum=总像素/2
greenZZHD=i;
for(i=0;i&256;i++)
sumBlueZZHD=sumBlueZZHD+Blue[i];
if(sumBlueZZHD&=m_nImage/6)
//m_nImage被分成3份RGB并且sum=总像素/2
blueZZHD=i;
dlg.m_redZZHD.Format(&%d&,redZZHD);
dlg.m_greenZZHD.Format(&%d&,greenZZHD);
dlg.m_blueZZHD.Format(&%d&,blueZZHD);
/*标准差:标准差=方差的算术平方根
方差s^2=[(x1-x)^2+(x2-x)^2+......(xn-x)^2]/n
/* 算法:不用开m_nImage数组进行计算 用num[256]中数进行
/* 方差=(平均灰度-i)*(平均灰度-i)*Red[i]
有Red[i]个灰度值为i的数
float redBZC,greenBZC,blueBZC;
double redFC=0,greenFC=0,blueFC=0;
for(i=0;i&256;i++)
redFC=redFC+(pinRedHD-i)*(pinRedHD-i)*Red[i];
//有Red[i]个像素i
greenFC=greenFC+(pinGreenHD-i)*(pinGreenHD-i)*Green[i];
blueFC=blueFC+(pinBlueHD-i)*(pinBlueHD-i)*Blue[i];
redBZC=sqrt(redFC*3/m_nImage);
greenBZC=sqrt(greenFC*3/m_nImage);
blueBZC=sqrt(blueFC*3/m_nImage);
dlg.m_redBZC.Format(&%.2lf&,redBZC);
dlg.m_greenBZC.Format(&%.2lf&,greenBZC);
dlg.m_blueBZC.Format(&%.2lf&,blueBZC);
//重点必须添加该语句才能弹出对话框
if(dlg.DoModal()==IDOK)
}& & & & 第五步:此时运行结果如下图所示,打开图片可以显示参数。
2.建立对话框与View联系并绘制直方图
& & & & 重点(极其重要*)
& & & & (1) 如何在MFC中(View中)实现对子对话框的画图或直方图响应?
& & & & 解决方法:在子对话框中.cpp文件中实现画图响应,不要再View.cpp中实现,否则图像会以menu背景为坐标,而在ImageZFTDlg.cpp中建立OnPaint函数实现画图,它默认会以子对话框为标准。
& & & & (2) 如何把View.cpp中的图片像素直方图信息传递给子对话框ImageZFTDlg.cpp呢?
& & & & 解决方法:如果自定义ImageStruct.h中建立全局变量,每个.cpp中引用该头文件调用总是报错(未知),所以我在View.h中建立一个全局变量int Red[256];再在子文件.cpp中函数里调用该全局变量即可extern int Red[256],这是非常重要的一个C语言知识。
& & & & (3) 画图函数OnPaint()参考源代码中详细注释。
& & & & 如何绘制坐标轴、文字、图像,其实自己绘制而没调用第三方库还是挺有意思的。
& & & & 第一步:建立画直方图函数OnPaint
& & & & 打开类向导(Ctrl+W),类名选择CImageZFTDlg,IDs选择CImageZFTDlg,在Message函数中建立WM_PAINT映射,默认函数名为OnPaint建立函数void CImageZFTDlg::OnPaint()
& & & & 第二步:绘制直方图大致思想如下
& & & & (1) 重点:获取要绘制直方图的位置和图像资源的对应号ID(IDC_STATIC_KJ 框架),我当时认为绘制直方图只能绘制到”图像“控件IDC中,不能是对话框IDD。
& & & & CWnd *pWnd = GetDlgItem(IDC_STATIC_KJ);
& & & & CDC *pDC = pWnd-&GetDC();
& & & & (2) 获取对话框矩形的长和宽
& & & & CR
& & & & GetDlgItem(IDC_STATIC_KJ)-&GetWindowRect(&rectpic);
& & & & (3) 创建画笔对象并对画笔进行颜色设置
& & & & CPen *RedPen = new CPen();
& & & & RedPen-&CreatePen(PS_SOLID,1RGB(255,0,0));
& & & & (4) 选中当前画笔并保存以前画笔
& & & & CGdiObject *RedOlderPen = pDC-&SelectObject(RedPen);
& & & & (5) 绘制直方图(图像坐标自己算)
& & & & 矩形 pDC-&Rectangle(9,327,312,468);
& & & & 移动 pDC-&MoveTo(15,331);
& & & & 直线 pDC-&LineTo(15,488);
& & & & 文字 pDC-&TextOut(15+48*i,450,str);
& & & & (6) 恢复以前画笔
& & & & pDC-&SelectObject(RedOlderPen);
& & & & delete RedP
& & & & ReleaseDC(pDC);
& & & & 第三步:源代码与详细注释思想
& & & & 在ImageZFTDlg.cpp中修改OnPaint函数:
//绘制原图直方图*//
void CImageZFTDlg::OnPaint()
CPaintDC dc(this); // device context for painting
// TODO: Add your message handler code here
/* 重点知识:(百度)
/* 如何在View.cpp中把一个变量的值传给其它对话框
/* 错误一:在View.h中定义的pubic变量只能在View.cpp中用
/* 错误二:定义一个Struct.h中存全局变量,在2个函数中分别调用#include &Struct.h&
/* 解决方法一: (CSDN 不会)参数用 A& a 两个对话框里都可以访问a
/* 解决方法二: (CSDN 不会)重载
/* 解决:在View.cpp中定义全局变量 void CBmpDrawView::OnZftYt() 前面 并函数中操作
在dialog的cpp中即void CTestZFTDlg::OnPaint()中在定义一个extern int a
extern int Red[256],Green[256],Blue[256];
/*写在该空间中可以省略Invalidate()语句*/
/*获取控件的CDC指针*/
GetDlgItem(IDC_STATIC_KJ)-&GetWindowRect(&rectpic);
x=rectpic.Width();
y=rectpic.Height();
CWnd *pWnd=GetDlgItem(IDC_STATIC_KJ);
CDC *pDC=pWnd-&GetDC();
/*重点:画直方图 红色
CPen *RedPen=new CPen();
//创建画笔对象
RedPen-&CreatePen(PS_SOLID,1,RGB(255,0,0));
//红色画笔
CGdiObject *RedOlderPen=pDC-&SelectObject(RedPen);
//选中当前红色画笔并保存以前的画笔
pDC-&Rectangle(9,16,312,147);
//画一个矩形框
pDC-&MoveTo(15,20);
//绘制坐标轴
pDC-&LineTo(15,128);
pDC-&LineTo(305,128);
pDC-&MoveTo(305,128);
//绘制X箭头
pDC-&LineTo(300,123);
//绘制上边箭头
pDC-&MoveTo(305,128);
pDC-&LineTo(300,133);
//绘制下边箭头
pDC-&MoveTo(15,20);
//绘制Y箭头
pDC-&LineTo(10,25);
//绘制左边箭头
pDC-&MoveTo(15,20);
pDC-&LineTo(20,25);
//绘制右边箭头
/* TextOut函数功能:
/* 该函数用当前选择的字体、背景颜色和正文颜色将一个字符串写到指定位置
/* BOOL TextOut(HDC hdc,int x,int y,LPCTSTR str,int numStr)
/* 表示:x起始坐标,y起始坐标,字符串,字符串中字符个数
/* SetTextColor函数功能:
/* 设置指定设备环境(HDC)的字体颜色
/* SetTextColor (HDC, COLORREF) 如:SetTextColor(HDC,RGB(255,0,0));
for(i=0;i&=5;i++)
//写X轴刻度线
str.Format(&%d&,i*50);
//0-255之间添加6个刻度值
pDC-&SetTextColor(RGB(255,0,255));
//设置字体颜色
pDC-&TextOut(15+48*i,130,str);
//输出字体
pDC-&MoveTo(15+48*i,128);
//绘制X轴刻度
pDC-&LineTo(15+48*i,125);
for(i=0;i&=5;i++)
//写Y轴刻度线
pDC-&MoveTo(15,128-20*i);
//绘制Y轴刻度
pDC-&LineTo(18,128-20*i);
/*绘制直方图主要的代码*/
for(i=1;i&256;i++)
pDC-&MoveTo(15+i,128);
if( (128-16) & (Red[i]/40) )
pDC-&LineTo(15+i,128-(Red[i]/40));
pDC-&LineTo(15+i,16);
//超过矩形的画矩形高
/*重点:画直方图 绿色
CPen *GreenPen=new CPen();
//创建画笔对象
GreenPen-&CreatePen(PS_SOLID,1,RGB(0,255,0));
//绿色画笔
CGdiObject *GreenOlderPen=pDC-&SelectObject(GreenPen);
pDC-&Rectangle(9,167,312,308);
//画一个矩形框
pDC-&MoveTo(15,171);
//绘制坐标轴
pDC-&LineTo(15,288);
pDC-&LineTo(305,288);
pDC-&MoveTo(305,288);
//绘制X箭头
pDC-&LineTo(300,283);
//绘制上边箭头
pDC-&MoveTo(305,288);
pDC-&LineTo(300,293);
//绘制下边箭头
pDC-&MoveTo(15,171);
//绘制Y箭头
pDC-&LineTo(10,176);
//绘制左边箭头
pDC-&MoveTo(15,171);
pDC-&LineTo(20,176);
//绘制右边箭头
for(i=0;i&=5;i++)
//写X轴刻度线
str.Format(&%d&,i*50);
//0-255之间添加6个刻度值
pDC-&SetTextColor(RGB(255,0,255));
//设置字体颜色
pDC-&TextOut(15+48*i,290,str);
//输出字体
pDC-&MoveTo(15+48*i,288);
//绘制X轴刻度
pDC-&LineTo(15+48*i,285);
for(i=0;i&=5;i++)
//写Y轴刻度线
pDC-&MoveTo(15,288-20*i);
//绘制Y轴刻度
pDC-&LineTo(18,288-20*i);
/*绘制直方图主要的代码*/
for(i=1;i&256;i++)
pDC-&MoveTo(15+i,288);
if( (288-167) & (Green[i]/40) )
pDC-&LineTo(15+i,288-(Green[i]/40));
pDC-&LineTo(15+i,167);
//超过矩形的画矩形高
/*重点:画直方图 蓝色
CPen *BluePen=new CPen();
//创建画笔对象
BluePen-&CreatePen(PS_SOLID,1,RGB(0,0,255));
//蓝色画笔
CGdiObject *BlueOlderPen=pDC-&SelectObject(BluePen);
pDC-&Rectangle(9,327,312,468);
//画一个矩形框
pDC-&MoveTo(15,331);
//绘制坐标轴
pDC-&LineTo(15,448);
pDC-&LineTo(305,448);
pDC-&MoveTo(305,448);
//绘制X箭头
pDC-&LineTo(300,443);
//绘制上边箭头
pDC-&MoveTo(305,448);
pDC-&LineTo(300,453);
//绘制下边箭头
pDC-&MoveTo(15,331);
//绘制Y箭头
pDC-&LineTo(10,336);
//绘制左边箭头
pDC-&MoveTo(15,331);
pDC-&LineTo(20,336);
//绘制右边箭头
for(i=0;i&=5;i++)
//写X轴刻度线
str.Format(&%d&,i*50);
//0-255之间添加6个刻度值
pDC-&SetTextColor(RGB(255,0,255));
//设置字体颜色
pDC-&TextOut(15+48*i,450,str);
//输出字体
pDC-&MoveTo(15+48*i,448);
//绘制X轴刻度
pDC-&LineTo(15+48*i,445);
for(i=0;i&=5;i++)
//写Y轴刻度线
pDC-&MoveTo(15,448-20*i);
//绘制Y轴刻度
pDC-&LineTo(18,448-20*i);
/*绘制直方图主要的代码*/
for(i=1;i&256;i++)
pDC-&MoveTo(15+i,448);
if( (448-327) & (Blue[i]/40) )
pDC-&LineTo(15+i,448-(Blue[i]/40));
pDC-&LineTo(15+i,327);
//超过矩形的画矩形高
//恢复以前的画笔
pDC-&SelectObject(RedOlderPen);
pDC-&SelectObject(GreenOlderPen);
pDC-&SelectObject(BlueOlderPen);
delete RedP
delete GreenP
delete BlueP
ReleaseDC(pDC);
// Do not call CDialog::OnPaint() for painting messages
}& & & & 此时运行程序即可显示直方图。
& & & & 最后还是希望文章对你有所帮助,如果文章有不足或错误之处,请海涵~文章不仅仅讲述了直方图相关的知识,同时文章也给你提供了一种绘制坐标图像的思想和详细注释。有时候一直怀疑回忆这些知识会让我停滞不前,但心安即好,何必在意!
& & & & 从来没有什么终南捷径和大神,真正的捷径只有三个:坚持、专注、认真。其他的都是细枝末节,做到这三个,其他的自然而然都会拥有。——同学CY
& & & (By:Eastmount
下午3点 &&http://blog.csdn.net/eastmount/)
> 本站内容系网友提交或本网编辑转载,其目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。如涉及作品内容、版权和其它问题,请及时与本网联系,我们将在第一时间删除内容!
本文主要讲述基于VC++6.0 MFC图像处理的应用知识,主要结合自己大三所学课程&数字图像处理&及课件进行讲解,主要通过MFC单文档视图实现显示BMP格式图片,并通过Bitmap进行灰度处理.图片采样和量化功能.
个人认为对初学者VC++6.0可能还是很值得学习的工具,所以采用它来讲解,而不是VS或C#.同时文章 ...
本文主要讲述基于VC++6.0 MFC图像处理的应用知识,主要结合自己大三所学课程&数字图像处理&及课件进行讲解,主要通过MFC单文档视图实现显示BMP图片点运算处理,包括图像灰度线性变换.灰度非线性变换.图像阈值化处理.图像均衡化处理等知识,并结合前一篇论文灰度直方图进行展示 .同时文章比较详细基础,希望该篇文章对你有所帮助,尤 ...
本文主要讲述基于VC++6.0 MFC图像处理的应用知识,主要结合自己大三所学课程&数字图像处理&及课件进行讲解,主要通过MFC单文档视图实现显示BMP图像增强处理,包括图像普通平滑.高斯平滑.不同算子的图像锐化知识.希望该篇文章对你有所帮助,尤其是初学者和学习图像处理的学生.
一.MFC详解显示BMP格式图片
本文主要讲述基于VC++6.0 MFC图像处理的应用知识,主要结合自己大三所学课程&数字图像处理&及课件进行讲解,主要通过MFC单文档视图实现显示BMP图片空间几何变换,包括图像平移.图形旋转.图像反转倒置镜像和图像缩放的知识.同时文章比较详细基础,没有采用GDI+获取矩阵,而是通过读取BMP图片信息头和矩阵像素实现变换,希望该篇文 ...
利用opencv绘制 灰度直方图 RGB直方图 HSV直方图 直方图均衡化 灰度直方图介绍: /wen_sift/blog/item/83fd56ca3e6b1b36b600c887.html 灰度直方图均衡化: /wen_sift/blog/item/b808fd0d9f67392 ...
本文主要是讲述&数字图像处理&系列栏目中的第一篇文章.主要详细介绍了BMP图片格式,同时使用C++和MFC显示BMP格式,主要结合自己的&数字图像处理&课程和以前的项目叙述讲解. 一.BMP图片格式定义 BMP文件格式是Windows操作系统推荐和支持的标准图像文件格式,是一种将内存或显示器的图像数据不经过压缩而直接按位存盘的文件格式 ...
本文是讲述&数字图像处理&系列文章,继上篇讲述BMP格式图片和显示后,该篇讲述如何对单文档进行分割.主要是采用CSplitterWnd静态分割窗口显示图片等相关知识.本文主要结合自己的课程及常用图片软件讲解. 一. CSplitterWnd静态分割窗口 1.CSplitterWnd类基础知识 (该部分引用:百度百科和麦田里的稻草人博客) CSpl ...
从上一个section3.2到现在又过去一段时间了,断断续续终于把section3.3的直方图那些事弄出来了,还是那样:不求速度与健壮性,但求自己取实现一下,尽量自己去写代码,不用现成的函数.
&数字图像处理 Digital Image Processing-3E冈萨雷斯&(后面简称&DIP&)的section3 ...

我要回帖

更多关于 conveyancing 的文章

 

随机推荐