MFC对话框绘制灰度直方图
本文主要講述基于VC++6.0 MFC圖像處理的應(yīng)用知識(shí),主要結(jié)合自己大三所學(xué)課程《數(shù)字圖像處理》及課件進(jìn)行回憶講解,主要通過(guò)MFC單文檔視圖實(shí)現(xiàn)點(diǎn)擊彈出對(duì)話框繪制BMP圖片的灰度直方圖,再獲取平均灰度、中指灰度和標(biāo)準(zhǔn)差等值。文章比較詳細(xì)基礎(chǔ),希望該篇文章對(duì)你有所幫助~
? ? ? ?【數(shù)字圖像處理】一.MFC詳解顯示BMP格式圖片
? ? ? ?【數(shù)字圖像處理】二.MFC單文檔分割窗口顯示圖片
? ? ? ?【數(shù)字圖像處理】三.MFC實(shí)現(xiàn)圖像灰度、采樣和量化功能詳解
? ? ? ??免費(fèi)資源下載地址:
? ? ? ??http://download.csdn.net/detail/eastmount/8757243
?
一. 程序運(yùn)行結(jié)果
? ? ? ? 該篇文章主要是在上一篇文章基礎(chǔ)上進(jìn)行的講解,其中當(dāng)打開(kāi)一張BMP圖像后,點(diǎn)擊”直方圖“-》”顯示原圖直方圖“如下。
?
二. 灰度直方圖原理
? ? ? ? 什么是灰度直方圖?
? ? ? ? 灰度直方圖(histogram)是灰度級(jí)的函數(shù),描述的是圖像中每種灰度級(jí)像素的個(gè)數(shù),反映圖像中每種灰度出現(xiàn)的頻率。橫坐標(biāo)是灰度級(jí),縱坐標(biāo)是灰度級(jí)出現(xiàn)的頻率。
? ? ? ??對(duì)于連續(xù)圖像,平滑地從中心的高灰度級(jí)變化到邊緣的低灰度級(jí)。直方圖定義為:
? ? ? ??其中A(D)為閾值面積函數(shù):為一幅連續(xù)圖像中被具有灰度級(jí)D的所有輪廓線所包圍的面積。對(duì)于離散函數(shù),固定ΔD為1,則:H(D)=A(D)-A(D+1)
? ? ? ??色彩直方圖是高維直方圖的特例,它統(tǒng)計(jì)色彩的出現(xiàn)頻率,即色彩概率分布信息。
? ? ? ??通常這需要一定的量化過(guò)程,將色彩分成若干互不重疊的種類。一般不直接在RGB色彩空間中統(tǒng)計(jì),而是在將亮度分離出來(lái)后,對(duì)代表色彩部分的信息進(jìn)行統(tǒng)計(jì),如在HSI空間的HS子空間、YUV空間的UV子空間,以及其它反映人類視覺(jué)特點(diǎn)的彩色空間表示中進(jìn)行。
? ? ? ? 其中直方圖的計(jì)算方法如下:
? ? ? ??依據(jù)定義,若圖像具有L(通常L=256,即8位灰度級(jí))級(jí)灰度,則大小為MxN的灰度圖像f(x,y)的灰度直方圖hist[0…L-1]可用如下計(jì)算獲得。
? ? ??? 1、初始化 hist[k]=0; k=0,…,L-1?
? ? ? ? 2、統(tǒng)計(jì) hist[f(x,y)]++; x=0,…,M-1, y =0,…,N-1?
? ? ? ? 3、歸一化 hist[f(x,y)]/=M*N?
? ? ? ? 那么說(shuō)了這么多,直方圖究竟有什么作用呢?
? ? ? ? 在使用輪廓線確定物體邊界時(shí),通過(guò)直方圖更好的選擇邊界閾值,進(jìn)行閾值化處理;對(duì)物體與背景有較強(qiáng)對(duì)比的景物的分割特別有用;簡(jiǎn)單物體的面積和綜合光密度IOD可以通過(guò)圖像的直方圖求得。
?
?
三. 程序?qū)崿F(xiàn)
?
1.建立直方圖對(duì)話框
? ? ? ?第一步:創(chuàng)建Dialog
? ? ? ? 將視圖切換到ResourceView界面,選中Dialog右鍵鼠標(biāo)新建一個(gè)Dialog,并新建一個(gè)名為IDD_DIALOG_ZFT,設(shè)置成下圖對(duì)話框。
?
? ? ? ? 右鍵添加屬性如下:
? ? ? ? 對(duì)話框-原始直方圖-IDD_DIALOG_ZFT
? ? ? ? 組框-RGB-IDC_STATIC_RGB
? ? ? ??圖像-框架-IDC_STATIC_KJ-蝕刻(重點(diǎn):有它才能添加直方圖在此處,注意GetDlgItem()函數(shù)中是IDC而不是IDD對(duì)話框)
? ? ? ? 添加蝕刻線(圖像蝕刻形成的直線)形如圖中的3個(gè)矩形框,并添加靜態(tài)文本:Red、Green、Blue、紅、綠、藍(lán)、像素、平均灰度、中值灰度、標(biāo)準(zhǔn)差;這些靜態(tài)文本都是IDC_STATIC且為默認(rèn)屬性
? ? ? ? 添加紅色4個(gè)值(Static)、綠色4個(gè)值、藍(lán)色4個(gè)值,分別為:
? ? ? ? IDC_STATIC_XS_RED(GREEN BLUE)對(duì)應(yīng)像素XS
? ? ? ? IDC_STATIC_PJHD_RED(GREEN BLUE)對(duì)應(yīng)平均灰度PJHD
? ? ? ? IDC_STATIC_ZZHD_RED(GREED BLUE)對(duì)應(yīng)中值灰度ZZHD
? ? ? ? IDC_STATIC_BZC_RED(GREEN BLUE)對(duì)應(yīng)標(biāo)準(zhǔn)差BZC
?
? ? ? ?第二步:建立類向?qū)FC ClassWizard
? ? ? ? (1) 在對(duì)話框資源模板空白區(qū)雙擊鼠標(biāo)(Ctrl+W),創(chuàng)建一個(gè)新類,命名為CImageZFTDlg會(huì)自動(dòng)生成它的.h和.cpp文件。在類向?qū)е羞x中類名CImageZFTDlg,IDs為CImageZFTDlg,WM_INITDIALOG建立這個(gè)函數(shù)用于初始化。
? ? ? ? (2) 打開(kāi)類向?qū)?#xff0c;選擇Member Variables頁(yè)面,添加如下變量,類型均為CString。
? ? ? ? 像素 m_redXS、m_greenXS、m_blueXS
? ? ? ? 標(biāo)準(zhǔn)差 m_redBZC、m_greeenBZC、m_blueBZC
? ? ? ? 平均灰度 m_redPJHD、m_greenPJHD、m_bluePJHD
? ? ? ? 中值灰度 m_redZZHD、m_greenZZHD、m_blueZZHD
? ? ? ? (3) 在View.cpp中添加直方圖的頭文件 #include "ImageZFTDlg.h"
? ? ? ??第三步:設(shè)置菜單欄調(diào)用直方圖對(duì)話框
? ? ? ? (1) 將視圖切換到ResourceView界面,選中Menu,在IDR_MAINFRAM中添加菜單項(xiàng)“直方圖”,菜單屬性中選擇“彈出”,在“直方圖”中添加子菜單“顯示原圖直方圖”。
? ? ? ? (2) 設(shè)置其屬性為ID_ZFT_YT(顯示直方圖原圖),同時(shí)建立類向?qū)?#xff0c;選擇ID_ZFT_YT(IDs),通過(guò)COMMAND建立顯示直方圖函數(shù)OnZftYt()。
? ? ? ?第四步:添加代碼及計(jì)算4個(gè)值
? ? ? ? 在ImageProcessingView.cpp中添加如下代碼,注釋中有如何求平均灰度、中值灰度和標(biāo)準(zhǔn)差的消息算法過(guò)程。
//引用顯示直方圖頭文件
#include "ImageZFTDlg.h"
#include "math.h"
/*全局變量在TestZFTDlg.cpp中引用 用extern*/
int Red[256],Green[256],Blue[256];
/**************************************************/
/* 添加直方圖顯示功能,并在直方圖下方顯示相關(guān)信息
/* 如平均灰度、中值灰度、標(biāo)準(zhǔn)差和像素總數(shù)
/* ID_ZFT_YT:直方圖原圖顯示
/**************************************************/
void CImageProcessingView::OnZftYt()
{
if(numPicture==0) {
AfxMessageBox("載入圖片后才能顯示原圖直方圖!",MB_OK,0);
return;
}
AfxMessageBox("顯示原圖直方圖!",MB_OK,0);
CImageZFTDlg dlg;
//打開(kāi)臨時(shí)的圖片
FILE *fpo = fopen(BmpName,"rb");
fread(&bfh,sizeof(BITMAPFILEHEADER),1,fpo);
fread(&bih,sizeof(BITMAPINFOHEADER),1,fpo);
int i,j;
for(j=0;j<256;j++) { //定義數(shù)組并清零
Red[j]=0;
Green[j]=0;
Blue[j]=0;
}
//計(jì)算4個(gè)數(shù)據(jù)
unsigned char red,green,blue;
int IntRed,IntGreen,IntBlue; //強(qiáng)制轉(zhuǎn)換
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+IntRed;
if( IntRed>=0 && IntRed<256 ) Red[IntRed]++; //像素0-255之間
fread(&green,sizeof(char),1,fpo);
IntGreen=int(green);
sumGreenHD=sumGreenHD+IntGreen;
if( IntGreen>=0 && IntGreen<256 ) Green[IntGreen]++;
fread(&blue,sizeof(char),1,fpo);
IntBlue=int(blue);
sumBlueHD=sumBlueHD+IntBlue;
if( IntBlue>=0 && IntBlue<256 ) Blue[IntBlue]++;
}
fclose(fpo);
//像素:int型轉(zhuǎn)換為CString型
dlg.m_redXS.Format("%d",m_nImage);
dlg.m_greenXS.Format("%d",m_nImage);
dlg.m_blueXS.Format("%d",m_nImage);
//平均灰度值:計(jì)算24位bmp圖片的灰度值,我是記錄RGB中的所有平均值
float pinRedHD,pinGreenHD,pinBlueHD;
pinRedHD=sumRedHD*3/m_nImage;
pinGreenHD=sumGreenHD*3/m_nImage; //平均灰度=總灰度/總像素
pinBlueHD=sumBlueHD*3/m_nImage;
dlg.m_redPJHD.Format("%.2f",pinRedHD);
dlg.m_greenPJHD.Format("%.2f",pinGreenHD);
dlg.m_bluePJHD.Format("%.2f",pinBlueHD);
/****************************************************************/
/* 中值灰度:算法重點(diǎn)(黃凱大神提供)
/* 中值灰度:所有像素中的中位數(shù),應(yīng)該所有像素排序找到中間的灰度值
/* 算法:num[256]記錄各灰度出現(xiàn)次數(shù),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;
break;
}
}
for(i=0;i<256;i++)
{
sumGreenZZHD=sumGreenZZHD+Green[i];
if(sumGreenZZHD>=m_nImage/6) //m_nImage被分成3份RGB并且sum=總像素/2
{
greenZZHD=i;
break;
}
}
for(i=0;i<256;i++)
{
sumBlueZZHD=sumBlueZZHD+Blue[i];
if(sumBlueZZHD>=m_nImage/6) //m_nImage被分成3份RGB并且sum=總像素/2
{
blueZZHD=i;
break;
}
}
dlg.m_redZZHD.Format("%d",redZZHD);
dlg.m_greenZZHD.Format("%d",greenZZHD);
dlg.m_blueZZHD.Format("%d",blueZZHD);
/******************************************************************/
/*標(biāo)準(zhǔn)差:標(biāo)準(zhǔn)差=方差的算術(shù)平方根
/* 方差s^2=[(x1-x)^2+(x2-x)^2+......(xn-x)^2]/n
/* 算法:不用開(kāi)m_nImage數(shù)組進(jìn)行計(jì)算 用num[256]中數(shù)進(jìn)行
/* 方差=(平均灰度-i)*(平均灰度-i)*Red[i] 有Red[i]個(gè)灰度值為i的數(shù)
/******************************************************************/
float redBZC,greenBZC,blueBZC; //標(biāo)準(zhǔn)差
double redFC=0,greenFC=0,blueFC=0; //方差
for(i=0;i<256;i++)
{
redFC=redFC+(pinRedHD-i)*(pinRedHD-i)*Red[i]; //有Red[i]個(gè)像素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);
//重點(diǎn)必須添加該語(yǔ)句才能彈出對(duì)話框
if(dlg.DoModal()==IDOK)
{
}
}
? ? ? ? 第五步:此時(shí)運(yùn)行結(jié)果如下圖所示,打開(kāi)圖片可以顯示參數(shù)。
?
2.建立對(duì)話框與View聯(lián)系并繪制直方圖
? ? ? ??重點(diǎn)(極其重要*)
? ? ? ??(1) 如何在MFC中(View中)實(shí)現(xiàn)對(duì)子對(duì)話框的畫(huà)圖或直方圖響應(yīng)?
? ? ? ? 解決方法:在子對(duì)話框中.cpp文件中實(shí)現(xiàn)畫(huà)圖響應(yīng),不要再View.cpp中實(shí)現(xiàn),否則圖像會(huì)以menu背景為坐標(biāo),而在ImageZFTDlg.cpp中建立OnPaint函數(shù)實(shí)現(xiàn)畫(huà)圖,它默認(rèn)會(huì)以子對(duì)話框?yàn)闃?biāo)準(zhǔn)。
? ? ? ??(2) 如何把View.cpp中的圖片像素直方圖信息傳遞給子對(duì)話框ImageZFTDlg.cpp呢?
? ? ? ? 解決方法:如果自定義ImageStruct.h中建立全局變量,每個(gè).cpp中引用該頭文件調(diào)用總是報(bào)錯(cuò)(未知),所以我在View.h中建立一個(gè)全局變量int Red[256];再在子文件.cpp中函數(shù)里調(diào)用該全局變量即可extern int Red[256],這是非常重要的一個(gè)C語(yǔ)言知識(shí)。
? ? ? ??(3) 畫(huà)圖函數(shù)OnPaint()參考源代碼中詳細(xì)注釋。
? ? ? ? 如何繪制坐標(biāo)軸、文字、圖像,其實(shí)自己繪制而沒(méi)調(diào)用第三方庫(kù)還是挺有意思的。
? ? ? ??第一步:建立畫(huà)直方圖函數(shù)OnPaint
? ? ? ? 打開(kāi)類向?qū)?Ctrl+W),類名選擇CImageZFTDlg,IDs選擇CImageZFTDlg,在Message函數(shù)中建立WM_PAINT映射,默認(rèn)函數(shù)名為OnPaint建立函數(shù)void CImageZFTDlg::OnPaint()
? ? ? ??第二步:繪制直方圖大致思想如下
? ? ? ? (1) 重點(diǎn):獲取要繪制直方圖的位置和圖像資源的對(duì)應(yīng)號(hào)ID(IDC_STATIC_KJ 框架),我當(dāng)時(shí)認(rèn)為繪制直方圖只能繪制到”圖像“控件IDC中,不能是對(duì)話框IDD。
? ? ? ??CWnd *pWnd = GetDlgItem(IDC_STATIC_KJ);
? ? ? ? CDC *pDC = pWnd->GetDC();
? ? ? ? (2) 獲取對(duì)話框矩形的長(zhǎng)和寬
? ? ? ??CRect rectpic;
? ? ? ? GetDlgItem(IDC_STATIC_KJ)->GetWindowRect(&rectpic);
? ? ? ? (3) 創(chuàng)建畫(huà)筆對(duì)象并對(duì)畫(huà)筆進(jìn)行顏色設(shè)置
? ? ? ??CPen *RedPen = new CPen();
? ? ? ? RedPen->CreatePen(PS_SOLID,1RGB(255,0,0));
? ? ? ? (4) 選中當(dāng)前畫(huà)筆并保存以前畫(huà)筆
? ? ? ??CGdiObject *RedOlderPen = pDC->SelectObject(RedPen);
? ? ? ? (5) 繪制直方圖(圖像坐標(biāo)自己算)
? ? ? ??矩形 pDC->Rectangle(9,327,312,468);
? ? ? ? 移動(dòng) pDC->MoveTo(15,331);
? ? ? ? 直線 pDC->LineTo(15,488);
? ? ? ? 文字 pDC->TextOut(15+48*i,450,str);
? ? ? ? (6) 恢復(fù)以前畫(huà)筆
? ? ? ??pDC->SelectObject(RedOlderPen);
? ? ? ? delete RedPen;
? ? ? ? ReleaseDC(pDC);
? ? ? ??第三步:源代碼與詳細(xì)注釋思想
? ? ? ? 在ImageZFTDlg.cpp中修改OnPaint函數(shù):
//****************繪制原圖直方圖*********************//
void CImageZFTDlg::OnPaint()
{
CPaintDC dc(this); // device context for painting
// TODO: Add your message handler code here
/********************************************************************************/
/* 重點(diǎn)知識(shí):(百度)
/* 如何在View.cpp中把一個(gè)變量的值傳給其它對(duì)話框
/*
/* 錯(cuò)誤一:在View.h中定義的pubic變量只能在View.cpp中用
/* 錯(cuò)誤二:定義一個(gè)Struct.h中存全局變量,在2個(gè)函數(shù)中分別調(diào)用#include "Struct.h"
/*
/* 解決方法一: (CSDN 不會(huì))參數(shù)用 A& a 兩個(gè)對(duì)話框里都可以訪問(wèn)a
/* 解決方法二: (CSDN 不會(huì))重載
/*
/* 解決:在View.cpp中定義全局變量 void CBmpDrawView::OnZftYt() 前面 并函數(shù)中操作
/* 在dialog的cpp中即void CTestZFTDlg::OnPaint()中在定義一個(gè)extern int a
/********************************************************************************/
extern int Red[256],Green[256],Blue[256];
/*寫(xiě)在該空間中可以省略Invalidate()語(yǔ)句*/
/*獲取控件的CDC指針*/
CRect rectpic;
GetDlgItem(IDC_STATIC_KJ)->GetWindowRect(&rectpic);
int x,y;
x=rectpic.Width();
y=rectpic.Height();
CWnd *pWnd=GetDlgItem(IDC_STATIC_KJ);
CDC *pDC=pWnd->GetDC();
/***********************/
/*重點(diǎn):畫(huà)直方圖 紅色
/**********************/
CPen *RedPen=new CPen(); //創(chuàng)建畫(huà)筆對(duì)象
RedPen->CreatePen(PS_SOLID,1,RGB(255,0,0)); //紅色畫(huà)筆
CGdiObject *RedOlderPen=pDC->SelectObject(RedPen); //選中當(dāng)前紅色畫(huà)筆并保存以前的畫(huà)筆
/*畫(huà)圖*/
pDC->Rectangle(9,16,312,147); //畫(huà)一個(gè)矩形框
pDC->MoveTo(15,20); //繪制坐標(biāo)軸
pDC->LineTo(15,128); //Y豎軸
pDC->LineTo(305,128); //X橫軸
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函數(shù)功能:
/* 該函數(shù)用當(dāng)前選擇的字體、背景顏色和正文顏色將一個(gè)字符串寫(xiě)到指定位置
/* BOOL TextOut(HDC hdc,int x,int y,LPCTSTR str,int numStr)
/* 表示:x起始坐標(biāo),y起始坐標(biāo),字符串,字符串中字符個(gè)數(shù)
/*
/* SetTextColor函數(shù)功能:
/* 設(shè)置指定設(shè)備環(huán)境(HDC)的字體顏色
/* SetTextColor (HDC, COLORREF) 如:SetTextColor(HDC,RGB(255,0,0));
/**********************************************************************/
CString str;
int i;
for(i=0;i<=5;i++) //寫(xiě)X軸刻度線
{
str.Format("%d",i*50); //0-255之間添加6個(gè)刻度值
pDC->SetTextColor(RGB(255,0,255)); //設(shè)置字體顏色
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++) //寫(xiě)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));
else
pDC->LineTo(15+i,16); //超過(guò)矩形的畫(huà)矩形高
}
/**********************/
/*重點(diǎn):畫(huà)直方圖 綠色
/**********************/
CPen *GreenPen=new CPen(); //創(chuàng)建畫(huà)筆對(duì)象
GreenPen->CreatePen(PS_SOLID,1,RGB(0,255,0)); //綠色畫(huà)筆
CGdiObject *GreenOlderPen=pDC->SelectObject(GreenPen);
pDC->Rectangle(9,167,312,308); //畫(huà)一個(gè)矩形框
pDC->MoveTo(15,171); //繪制坐標(biāo)軸
pDC->LineTo(15,288); //Y豎軸
pDC->LineTo(305,288); //X橫軸
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++) //寫(xiě)X軸刻度線
{
str.Format("%d",i*50); //0-255之間添加6個(gè)刻度值
pDC->SetTextColor(RGB(255,0,255)); //設(shè)置字體顏色
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++) //寫(xiě)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));
else
pDC->LineTo(15+i,167); //超過(guò)矩形的畫(huà)矩形高
}
/**********************/
/*重點(diǎn):畫(huà)直方圖 藍(lán)色
/***************((*****/
CPen *BluePen=new CPen(); //創(chuàng)建畫(huà)筆對(duì)象
BluePen->CreatePen(PS_SOLID,1,RGB(0,0,255)); //藍(lán)色畫(huà)筆
CGdiObject *BlueOlderPen=pDC->SelectObject(BluePen);
pDC->Rectangle(9,327,312,468); //畫(huà)一個(gè)矩形框
pDC->MoveTo(15,331); //繪制坐標(biāo)軸
pDC->LineTo(15,448); //Y豎軸
pDC->LineTo(305,448); //X橫軸
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++) //寫(xiě)X軸刻度線
{
str.Format("%d",i*50); //0-255之間添加6個(gè)刻度值
pDC->SetTextColor(RGB(255,0,255)); //設(shè)置字體顏色
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++) //寫(xiě)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));
else
pDC->LineTo(15+i,327); //超過(guò)矩形的畫(huà)矩形高
}
//恢復(fù)以前的畫(huà)筆
pDC->SelectObject(RedOlderPen);
pDC->SelectObject(GreenOlderPen);
pDC->SelectObject(BlueOlderPen);
delete RedPen;
delete GreenPen;
delete BluePen;
ReleaseDC(pDC);
return;
// Do not call CDialog::OnPaint() for painting messages
}
? ? ? ??
//
轉(zhuǎn)載:https://blog.csdn.net/eastmount/article/details/46237463
?
總結(jié)
以上是生活随笔為你收集整理的MFC对话框绘制灰度直方图的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: QT中信号和槽的简单解释
- 下一篇: MFC制作打地鼠小游戏