📄 freestrechdlg.cpp
字号:
// FreeStrechDlg.cpp : implementation file
//
#include "stdafx.h"
#include "RSIP.h"
#include "FreeStrechDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CFreeStrechDlg dialog
CFreeStrechDlg::CFreeStrechDlg(CWnd* pParent /*=NULL*/)
: CDialog(CFreeStrechDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CFreeStrechDlg)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
CPoint *pPoint;
pPoint = new CPoint(0,0);
m_aPoints.Add(pPoint);
pPoint = new CPoint(255,255);
m_aPoints.Add(pPoint);
m_bTrace = FALSE;
for(int i=0; i<256; i++)
{
m_dwHistogram[i] = 0;
}
m_nSelPoint = -1;
}
CFreeStrechDlg::~CFreeStrechDlg()
{
CPoint *pPoint;
for(int i=0; i<m_aPoints.GetSize(); i++)
{
pPoint = (CPoint *)(m_aPoints[i]);
delete pPoint;
}
m_aPoints.RemoveAll();
}
void CFreeStrechDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CFreeStrechDlg)
// NOTE: the ClassWizard will add DDX and DDV calls here
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CFreeStrechDlg, CDialog)
//{{AFX_MSG_MAP(CFreeStrechDlg)
ON_WM_PAINT()
ON_BN_CLICKED(IDC_RESET, OnReset)
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_WM_MOUSEMOVE()
ON_BN_CLICKED(IDC_DELETEPOINT, OnDeletepoint)
ON_BN_CLICKED(IDC_AUTOCLIP, OnAutoclip)
ON_BN_CLICKED(IDC_ACTUALSIZE, OnActualsize)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CFreeStrechDlg message handlers
void CFreeStrechDlg::OnPaint()
{
CPaintDC dc(this);
RECT Rect;
// 设置绘制方式
dc.SetROP2(R2_COPYPEN);
// 画图象的现在直方图信息
SetRect(&Rect,7,7,117,100);
MapDialogRect(&Rect);
double dMaxRatio = 0;
double dXRatio = (double)(Rect.right-Rect.left)/255;
for(int i=0; i<256; i++)
{
if(dMaxRatio< m_dwHistogram[i])
dMaxRatio = m_dwHistogram[i];
}
dMaxRatio = (Rect.bottom-Rect.top)/dMaxRatio;
for(i=0; i<256; i++)
{
dc.MoveTo(int(i*dXRatio+Rect.left),int(Rect.bottom-dMaxRatio*m_dwHistogram[i]));
dc.LineTo(int(i*dXRatio+Rect.left),Rect.bottom);
}
// 设置一条45度参考线
CPen dashPen(PS_DASH,1,RGB(255,0,0));
CPen *pOldPen;
pOldPen = dc.SelectObject(&dashPen);
dc.MoveTo(Rect.left,Rect.bottom);
dc.LineTo(Rect.right,Rect.top);
dc.SelectObject(pOldPen);
SetRect(&Rect,7,100,117,115);
MapDialogRect(&Rect);
CPen Pen;
for(i=0; i<256; i++)
{
Pen.CreatePen(PS_SOLID,1,RGB(i,i,i));
pOldPen = dc.SelectObject(&Pen);
dc.MoveTo(int(i*dXRatio+Rect.left),Rect.bottom);
dc.LineTo(int(i*dXRatio+Rect.left),Rect.top);
dc.SelectObject(pOldPen);
Pen.DeleteObject();
}
// 画自由拉伸曲线
SetRect(&Rect,7,7,117,100);
MapDialogRect(&Rect);
CPoint *pPoint;
double dYRatio = (double)(Rect.bottom-Rect.top)/255;
int x;
int y;
CPen BluePen(PS_SOLID,1,RGB(0,0,255));
CPen RedPen(PS_SOLID,1,RGB(255,0,0));
CBrush RedBrush(RGB(0,0,255));
CBrush *pOldBrush;
for(i=0; i<m_aPoints.GetSize(); i++)
{
pPoint = (CPoint *)(m_aPoints[i]);
x = int(pPoint->x * dXRatio + Rect.left);
y = int(Rect.bottom - pPoint->y * dYRatio);
if(i!=0 && i!=m_aPoints.GetSize()-1)
{
pOldPen = dc.SelectObject(&RedPen);
pOldBrush = dc.SelectObject(&RedBrush);
dc.Rectangle(x-2,y-2,x+2,y+2);
dc.SelectObject(pOldPen);
dc.SelectObject(pOldBrush);
}
if(i==0)
{
dc.MoveTo(x,y);
}
else
{
pOldPen = dc.SelectObject(&BluePen);
dc.LineTo(x,y);
dc.SelectObject(pOldPen);
}
}
}
/*
void CFreeStrechDlg::OnPreview()
{
CRSIPApp *theApp = (CRSIPApp *)AfxGetApp();
CPoint *pPoint;
CPoint *pNextPoint;
for(int i=0; i<m_aPoints.GetSize()-1; i++)
{
pPoint = (CPoint *)(m_aPoints[i]);
pNextPoint = (CPoint *)(m_aPoints[i+1]);
for(int j=pPoint->x; j<pNextPoint->x; j++)
{
theApp->m_pLUTable[j] = pPoint->y+
(pNextPoint->y-pPoint->y)*(j-pPoint->x)/(pNextPoint->x-pPoint->x);
}
}
GetParent()->PostMessage(WM_COMMAND,
ID_PREVIEW,
0L);
}
*/
void CFreeStrechDlg::OnReset()
{
CPoint *pPoint;
for(int i=0; i<m_aPoints.GetSize(); i++)
{
pPoint = (CPoint *)(m_aPoints[i]);
delete pPoint;
}
m_aPoints.RemoveAll();
pPoint = new CPoint(0,0);
m_aPoints.Add(pPoint);
pPoint = new CPoint(255,255);
m_aPoints.Add(pPoint);
m_nSelPoint = -1;
RECT Rect;
SetRect(&Rect,7,7,117,100);
MapDialogRect(&Rect);
InvalidateRect(&Rect);
}
void CFreeStrechDlg::OnLButtonDown(UINT nFlags, CPoint point)
{
int x;
int y;
RECT Rect;
SetRect(&Rect,7,7,117,100);
MapDialogRect(&Rect);
if(point.x<Rect.left || point.y>Rect.right ||
point.y<Rect.top || point.y>Rect.bottom)
return;
x = (point.x-Rect.left)*255/(Rect.right-Rect.left);
y = (Rect.bottom-point.y)*255/(Rect.bottom-Rect.top);
CPoint *pPoint;
CPoint *pNextPoint;
for(int i=1; i<m_aPoints.GetSize()-1; i++)
{
pPoint = (CPoint *)(m_aPoints[i]);
if(abs(pPoint->x-x)<=5 && abs(pPoint->y-y)<=5)
break;
}
if(i == m_aPoints.GetSize()-1)
{
for(int i=0; i<m_aPoints.GetSize()-1; i++)
{
pPoint = (CPoint *)(m_aPoints[i]);
pNextPoint = (CPoint *)(m_aPoints[i+1]);
if(pPoint->x<x && pNextPoint->x>x)
break;
}
if(i < m_aPoints.GetSize()-1)
{
pPoint = new CPoint(x,y);
m_aPoints.InsertAt(i+1,pPoint);
Rect.left = Rect.left+1;
Rect.top = Rect.top+1;
Rect.right = Rect.right-1;
Rect.bottom = Rect.bottom-1;
InvalidateRect(&Rect);
}
}
else
{
SetCapture();
m_bTrace = TRUE;
m_nSelPoint = i;
pPoint = (CPoint *)(m_aPoints[i-1]);
pNextPoint = (CPoint *)(m_aPoints[i+1]);
double dRatioX = (double)(Rect.right-Rect.left)/255;
double dRatioY = (double)(Rect.bottom-Rect.top)/255;
int x1 = int(pPoint->x*dRatioX+Rect.left+0.5);
int x2 = int(pNextPoint->x*dRatioX+Rect.left);
RECT ClipRect;
SetRect(&ClipRect,x1,Rect.top,x2+1,Rect.bottom);
ClientToScreen(&ClipRect);
ClipCursor(&ClipRect);
}
CDialog::OnLButtonDown(nFlags, point);
}
void CFreeStrechDlg::OnLButtonUp(UINT nFlags, CPoint point)
{
if(m_bTrace)
{
ReleaseCapture();
m_bTrace = FALSE;
ClipCursor(NULL);
}
CDialog::OnLButtonUp(nFlags, point);
}
void CFreeStrechDlg::OnMouseMove(UINT nFlags, CPoint point)
{
int x;
int y;
RECT Rect;
SetRect(&Rect,7,7,117,100);
MapDialogRect(&Rect);
if(point.x<Rect.left || point.y>Rect.right ||
point.y<Rect.top || point.y>Rect.bottom)
return;
x = (point.x-Rect.left)*255/(Rect.right-Rect.left);
y = (Rect.bottom-point.y)*255/(Rect.bottom-Rect.top);
SetDlgItemInt(IDC_X,x);
SetDlgItemInt(IDC_Y,y);
CPoint *pPoint;
if(m_bTrace)
{
//DrawFreeLine(R2_NOTCOPYPEN);
pPoint = (CPoint *)(m_aPoints[m_nSelPoint]);
pPoint->x = x;
pPoint->y = y;
//DrawFreeLine(R2_COPYPEN);
Rect.left = Rect.left+1;
Rect.top = Rect.top+1;
Rect.right = Rect.right-1;
Rect.bottom = Rect.bottom-1;
InvalidateRect(&Rect);
}
CDialog::OnMouseMove(nFlags, point);
}
/*
void CFreeStrechDlg::DrawFreeLine(int mode)
{
CPaintDC dc(this);
RECT Rect;
// 设置绘图模式
int type = dc.GetROP2();
dc.SetROP2(mode);
// 设置绘图区域
SetRect(&Rect,7,7,117,100);
MapDialogRect(&Rect);
// 绘制自由拉伸曲线
CPoint *pPoint;
double dXRatio = (double)(Rect.right-Rect.left)/255;
double dYRatio = (double)(Rect.bottom-Rect.top)/255;
int x;
int y;
CPen BluePen(PS_SOLID,1,RGB(0,0,255));
CPen RedPen(PS_SOLID,1,RGB(255,0,0));
CBrush RedBrush(RGB(0,0,255));
CPen * pOldPen;
CBrush *pOldBrush;
for(int i=0; i<m_aPoints.GetSize(); i++)
{
pPoint = (CPoint *)(m_aPoints[i]);
x = int(pPoint->x*dXRatio+Rect.left);
y = int(Rect.bottom - pPoint->y*dYRatio);
if(i!=0 && i!=m_aPoints.GetSize()-1)
{
pOldPen = dc.SelectObject(&RedPen);
pOldBrush = dc.SelectObject(&RedBrush);
dc.Rectangle(x-2,y-2,x+2,y+2);
dc.SelectObject(pOldPen);
dc.SelectObject(pOldBrush);
}
if(i==0)
{
dc.MoveTo(x,y);
}
else
{
pOldPen = dc.SelectObject(&BluePen);
dc.LineTo(x,y);
dc.SelectObject(pOldPen);
}
}
// 恢复原有绘图模式
dc.SetROP2(type);
}
*/
void CFreeStrechDlg::OnDeletepoint()
{
int size = m_aPoints.GetSize();
if(m_nSelPoint != -1 &&
m_nSelPoint != 0 &&
m_nSelPoint != size)
{
CPoint * pPoint = NULL;
pPoint = (CPoint *)(m_aPoints[m_nSelPoint]);
delete pPoint;
m_aPoints.RemoveAt(m_nSelPoint);
Invalidate();
m_nSelPoint = -1;
}
}
// 自动截去直方图的两端,共1%。即每端0.5%。
void CFreeStrechDlg::OnAutoclip()
{
// 计算每端应截去的象素量
long totalPixels, clipPixels;
totalPixels = 0L;
for(int i=0; i<256; i++)
totalPixels = totalPixels + m_dwHistogram[i];
clipPixels = (totalPixels+100) / 200;
// 相关变量恢复初始状态
int size = m_aPoints.GetSize();
for(i=size-2; i>0; i--)
{
CPoint * pPoint = NULL;
pPoint = (CPoint *)(m_aPoints[i]);
delete pPoint;
m_aPoints.RemoveAt(i);
}
m_nSelPoint = -1;
// 计算截断的位置,并更改相关变量
long clip = 0L; //左面
i = 0;
while(clipPixels - clip >= 0)
{
clip = clip + m_dwHistogram[i];
i = i+1;
}
CPoint * pPoint = new CPoint(i-1,0);
m_aPoints.InsertAt(1,pPoint);
clip = 0L; //右面
i = 255;
while(clipPixels - clip >= 0)
{
clip = clip + m_dwHistogram[i];
i = i-1;
}
pPoint = new CPoint(i+1,255);
m_aPoints.InsertAt(2,pPoint);
// 画“自动截去”的曲线
Invalidate();
}
// 按图象的实际亮度范围进行截取
void CFreeStrechDlg::OnActualsize()
{
// 相关变量恢复初始状态
int size = m_aPoints.GetSize();
for(int i=size-2; i>0; i--)
{
CPoint * pPoint = NULL;
pPoint = (CPoint *)(m_aPoints[i]);
delete pPoint;
m_aPoints.RemoveAt(i);
}
m_nSelPoint = -1;
// 计算截断的位置,并更改相关变量
i = 0; //左面
while(m_dwHistogram[i] == 0)
i = i+1;
CPoint * pPoint = new CPoint(i,0);
m_aPoints.InsertAt(1,pPoint);
i = 255; //右面
while(m_dwHistogram[i] == 0)
i = i-1;
pPoint = new CPoint(i,255);
m_aPoints.InsertAt(2,pPoint);
// 画“自动截去”的曲线
Invalidate();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -