[计划]图象平移和灰度变换程序设计
*******************
实践教学
*******************
计算机与通信学院
2009年秋季学期
计算机图象处理综合训练
题
快递公司问题件快递公司问题件货款处理关于圆的周长面积重点题型关于解方程组的题及答案关于南海问题
目: 图象平移和灰度变换程序设计
专业班级:
姓 名:
学 号:
指导教师:
成 绩:
目 录
摘 要 .......................................................................... 1 一、 前言 ................................................................... 2 二、 算法分析与描述 ................................................ 3 2.1 图像的平移变换.........................3 2.2 灰级窗处理 ............................3 三、详细设计过程 ........................................................ 5 3.1 图像的平移变换.........................5 3.2灰级窗详细设计 .........................5 四、调试过程中出现的问题以及相应解决办法 ........... 7 五、程序运行截图及其说明 ......................................... 8 六、简单操作手册 ...................................................... 10 设计
总结
初级经济法重点总结下载党员个人总结TXt高中句型全总结.doc高中句型全总结.doc理论力学知识点总结pdf
..................................................................... 14 参考资料..................................................................... 15 致 谢 .......................................................................... 16 附 录 .......................................................................... 17
摘 要
图像灰度变换在这里主要实现灰级窗变化,图像几何变换同样也主要实现图像水平平移变换,选取若干张目标图像文件,在计算机图象驱动程序中完成相应的变换。其目标图像主要为24为真彩色图片。
在图像处理中主要用VC++编写图像处理程序并调用VC++图像处理的部分内部函数进行处理。通过程序实现图象水平平移和图像的灰度变换,对程序进行相应的调试,并且用图例进行测试,以验证程序的正确性与可用性。调试及测试时,通过相关信息,充分验证程序的可用性。本程序通篇均用C++写成,具有很高的严密性,具有很高的真实性与可靠性。可以通过VC++能够很好地达到图像处理的预期目的。
关键词 : 数字图像处理;灰度变换;几何变换;
一、 前言
计算机图像处理的实现主要以数学模型为基础,通过建立合适的算法来实现具体的图像处理,图象的灰度变换是图像的增强的主要的方法,要进行图象的灰度变换,必须知道图像增强的目标和所包含的几个组要的部分。
所谓图像增强,实际上要完成的工作通过将画面上重要的
内容
财务内部控制制度的内容财务内部控制制度的内容人员招聘与配置的内容项目成本控制的内容消防安全演练内容
增强突出,同时将不重要的内容进行适当的抑制,以此达到改善画面质量的方法。在此前提下,也就是说处理前后的图像的灰度范围都分布在[0,255],通过抑制非重要信息的对比度腾出空间给重要信息进行对比度的展宽。 几何变换是最常见的图像处理手段,通过对变形的图像进行几何校正,可以得出准确的图像。常用的几何变换功能包括图像的平移、图像的转置、图像的缩放、图像的旋转等。作为数字图像处理的一个重要部分,一般用Visual C++编程工具设计一个完整的应用程序,实现相应的图像几何变换功能和灰度变换。
二、 算法分析与描述 2.1 图像的平移变换
图像的平移变换就是将图像中的像素点按照要求的量进行垂直、水平移动。图像的水平处理,只是改变了原有景物在画面上的位置,而图像的内容不发生变化。
初始坐标为(x,y)的点经过平移(tx,ty)(以向右,向下为正方向)后,00
坐标变为(x,y)。这两点之间的关系是: 11
x=x+tx 10
y=y+ty 10
使用矩阵的形式来
表
关于同志近三年现实表现材料材料类招标技术评分表图表与交易pdf视力表打印pdf用图表说话 pdf
达如下:
100
x y x y 11 1 =00 1 ,,,,010
txty1
值得注意的是,一个数字图像(灰度图)是以一个矩阵来描述的,因此,如果不扩大存放处理后的矩阵的大小,则会出现图像的部分内容移出画面的情况。
2.2 灰级窗处理
灰级窗也称为灰度窗口,灰级窗可以看作是对比度扩展的一个特例,它是将某一区间的灰度级和其它部分(背景)分开,只显示指定灰度级范围内的信息。灰级窗的原理如图2-2所示
错误~未指定书签。 g
图2-2 灰级窗的原理
不难看出,只要令比度扩展中的α=γ=0就实现了灰级窗。我们只要给出范
围的两个端点,斜率β就可以用方程β(b-a)=255求出,灰级窗的原理和对比度扩展的原理类似。
三、详细设计过程 3.1 图像的平移变换
图像的平移处理,只改变了原有景物在画面的位置,而图像的内容不发生变化,采用数字图像坐标系,用下面的函数进行平移。
函数名称:
TranslationDIB()
参数:
* LPSTR lpDIBBits - 指向源DIB图像指针
* LONG lWidth - 源图像宽度(象素数)
* LONG lHeight - 源图像高度(象素数)
* LONG lXOffset - X轴平移量(象素数)
* LONG lYOffset - Y轴平移量(象素数)
* 返回值:
* BOOL - 平移成功返回TRUE,否则返回FALSE。
* 该函数用来水平移动DIB图像。函数不会改变图像的大小,移出的部分图像
3.2灰级窗详细设计
函数名称:GrayWindows()该函数用来对图像进行分段线性灰度变换,输入参数中包含了两个拐点的坐标;
函数名称:GetDibSaveDim();获得图象数据存储的高度和宽度;
函数名称:WIDTHBYTES(sizeImage.cx * 8); 计算图像每行的字节数;
输入参数:
CDib* pDib:指向CDib类的指针,含有原始图象信息 int nX1:分段线性灰度变换第一个拐点的X坐标 int nY1:分段线性灰度变换第一个拐点的Y坐标 int nX2:分段线性灰度变换第二个拐点的X坐标 int nY2:分段线性灰度变换第二个拐点的Y坐标 返回值: BOOL:成功返回TRUE,否则返回FALSE。
四、调试过程中出现的问题以及相应解决办法
在设计过程中首先遇到的问题是如何将复杂的算法用程序来描述出来,我通过查阅资料和认真阅读课本知识,经过不断和同学的探讨,最后终于使算法成型,初步完成了对算法的编程。
在程序初步完成后,在调试过程中我又遇到了新的问题,由于对Visual C++6.0的使用不是很熟练,使我在调试过程中不能很好的解决所出现的问题,这时我主动向老师请教,通过老师的指导,原来我的visual C++6.0软件有问题,经过重新安装后,使我的调试过程有了很快的进展,也是我对软件有了更
深刻的了解。
下面是我在程序调试总遇到的一个问题:经过仔细的分析发现原来是缺少一个头文件:#include "DlgGeoTran.h"。
图4.1 编译错误界面
五、程序运行截图及其说明
程序经运行后的操作界面,在该界面下可以打开相应的需处理的文件,如图5.1:
经平移后的图像如图5.2:
3(进行灰级窗处理,其参数设置界面如图5.3:
.
5.3 设置灰级窗数值界面
4.进行灰级窗处理后的图像如图5.4:
六、简单操作手册
1(在进行图像平移处理时,首先工程运行后弹出的界面如图6.1所示。
图6.1 运行结果界面
2.其次,参数设定分别制定其水平平移的距离里80和垂直方向的平移距离50,其参数设定界面所得的界面如图6.2所示。
图6.2参数设定界
3.导入要处理的图片,在对话框的几何变换中选定平移操作,经处理后所得的界面如图6.3所示,其中原图与变换后的图片进行对比如下:
图6.3 打开图片界面
(打开VC++环境重新选择灰度变换的程序,运行后在其对话框中选择灰度4
变换中的灰级窗的线性变换处理,接着进行参数设置,只需设置第一点Y坐标值为0,第二点Y坐标值为255,进行灰级窗处理的坐标设置界面,如图6.4所示。
.
6.4坐标设置界面
5.经灰度设置后按确认键便得到灰级窗处理后的图像,其界面如6.5所示。
图6.5图像界面
设计总结
通过短短两周的综合训练,我觉的我对图像处理的理解又更深了一层。原来在没有训练以前,我觉得所学的东西都是一些理论的没有什么实践的价值,但是这次让我知道不是仅仅这样,它对我们都很大的用处。
不仅使我掌握了怎样熟练的运用VC++,也对它的强大的功能、丰富的能力、方便灵活的使用、广泛的应用、高效率的目标程序、好的移植性等许多的优点有了很好的认识。而且还对图像处理的方法如灰级窗处理以及图像几何变换中的平移等都有了初步的掌握。
现在我被这图像处理的各种方法所深深地吸引,它真的是惟妙惟肖的,能满足人们各种不同的需求。
这次的综合训练真的让我获益匪浅。
参考资料
[1] 朱虹.计算机图象处理基础[M].北京,科学出版社, 2005. [2] K.R.Castleman. 计算机图象处理[M].北京,电子工业出版社,2002.
[3] 章毓晋.图像处理与分析-图像工程(上册)[M].北京,清华大学出社,2001.
[4] 张宏林编著.Visual C++计算机图象模式识别技术及工程实践[M].北京,人
民邮电出版社,2003.
[5] 黄维通.Visual C++面向对象与可视化程序设计[M].北京,清华大学社,
2003.
[6] R C.Gonzalez, R E.Woods, S L. Eddins著,阮秋琦,阮宇智等译.计算机
[M].北京,电子工业出版社,2005.图象处理(MATLAB版)
致 谢
此次数字图像处理综合训练是在柯铭老师的指导下顺利完成的,她在我的综合训练过程中提出了指导性的意见和
方案
气瓶 现场处置方案 .pdf气瓶 现场处置方案 .doc见习基地管理方案.doc关于群访事件的化解方案建筑工地扬尘治理专项方案下载
,并在课设期间对我们进行耐心地指导,对我的设计工作有很大的帮助,在此表示衷心的感谢。还有帮助过我的同学,是你们的支持和鼓励让我坚持到底,最终顺利完成综合训练,在此谢谢你们了。此外那些参考文献也带给我许多帮助,在此也感谢那些文献的作者以及他们编写的书。
附 录 图像的几何变换平移的函数:
/****************************************************************
**********
* 文件名:GeoTrans.cpp
*
* 图像几何变换API函数库:
*
* TranslationDIB1() - 图像平移
* TranslationDIB() - 图像平移 *****************************************************************
********/
#include "stdafx.h"
#include "geotrans.h"
#include "DIBAPI.h"
#include
#include
/****************************************************************
*********
*
* 函数名称:
* TranslationDIB1()
*
* 参数:
* LPSTR lpDIBBits - 指向源DIB图像指针
* LONG lWidth - 源图像宽度(象素数)
* LONG lHeight - 源图像高度(象素数)
* LONG lXOffset - X轴平移量(象素数)
* LONG lYOffset - Y轴平移量(象素数)
*
* 返回值:
* BOOL - 平移成功返回TRUE,否则返回FALSE。
*
* 说明:
* 该函数用来水平移动DIB图像。函数不会改变图像的大小,移出的部分图像
* 将截去,空白部分用白色填充。
*
*********************************************************************
***/
BOOL WINAPI TranslationDIB1(LPSTR lpDIBBits, LONG lWidth, LONG
lHeight, LONG lXOffset, LONG lYOffset) {
// 指向源图像的指针
LPSTR lpSrc;
// 指向要复制区域的指针
LPSTR lpDst;
// 指向复制图像的指针
LPSTR lpNewDIBBits;
HLOCAL hNewDIBBits;
// 象素在新DIB中的坐标
LONG i;
LONG j;
// 象素在源DIB中的坐标
LONG i0;
LONG j0;
// 图像每行的字节数
LONG lLineBytes;
// 计算图像每行的字节数
lLineBytes = WIDTHBYTES(lWidth * 8);
// 暂时分配内存,以保存新图像
hNewDIBBits = LocalAlloc(LHND, lLineBytes * lHeight);
if (hNewDIBBits == NULL)
{
// 分配内存失败
return FALSE;
}
// 锁定内存
lpNewDIBBits = (char * )LocalLock(hNewDIBBits);
// 每行
for(i = 0; i < lHeight; i++)
{
// 每列
for(j = 0; j < lWidth; j++)
{
// 指向新DIB第i行,第j个象素的指针
// 注意由于DIB中图像第一行其实保存在最后一行的位置,因
此lpDst
// 值不是(char *)lpNewDIBBits + lLineBytes * i + j,而是
// (char *)lpNewDIBBits + lLineBytes * (lHeight - 1 - i)
+ j
lpDst = (char *)lpNewDIBBits + lLineBytes * (lHeight - 1
- i) + j;
// 计算该象素在源DIB中的坐标
i0 = i - lXOffset;
j0 = j - lYOffset;
// 判断是否在源图范围内
if( (j0 >= 0) && (j0 < lWidth) && (i0 >= 0) && (i0 < lHeight))
{
// 指向源DIB第i0行,第j0个象素的指针
// 同样要注意DIB上下倒置的问题
lpSrc = (char *)lpDIBBits + lLineBytes * (lHeight - 1
- i0) + j0;
// 复制象素
*lpDst = *lpSrc;
}
else
{
// 对于源图中没有的象素,直接赋值为255
* ((unsigned char*)lpDst) = 255;
}
}
}
// 复制平移后的图像
memcpy(lpDIBBits, lpNewDIBBits, lLineBytes * lHeight);
// 释放内存
LocalUnlock(hNewDIBBits);
LocalFree(hNewDIBBits);
// 返回
return TRUE;
}
/****************************************************************
*********
*
* 函数名称:
* TranslationDIB()
*
* 参数:
* LPSTR lpDIBBits - 指向源DIB图像指针
* LONG lWidth - 源图像宽度(象素数)
* LONG lHeight - 源图像高度(象素数)
* LONG lXOffset - X轴平移量(象素数)
* LONG lYOffset - Y轴平移量(象素数)
*
* 返回值:
* BOOL - 平移成功返回TRUE,否则返回FALSE。
*
* 说明:
* 该函数用来水平移动DIB图像。函数不会改变图像的大小,移出的部分图像
* 将截去,空白部分用白色填充。
*
*********************************************************************
***/
BOOL WINAPI TranslationDIB(LPSTR lpDIBBits, LONG lWidth, LONG lHeight,
LONG lXOffset, LONG lYOffset)
{
// 平移后剩余图像在源图像中的位置(矩形区域)
CRect rectSrc;
// 平移后剩余图像在新图像中的位置(矩形区域)
CRect rectDst;
// 指向源图像的指针
LPSTR lpSrc;
// 指向要复制区域的指针
LPSTR lpDst;
// 指向复制图像的指针
LPSTR lpNewDIBBits;
HLOCAL hNewDIBBits;
// 指明图像是否全部移去可视区间
BOOL bVisible;
// 循环变量
LONG i;
// 图像每行的字节数
LONG lLineBytes;
// 计算图像每行的字节数
lLineBytes = WIDTHBYTES(lWidth * 8);
// 赋初值
bVisible = TRUE;
// 计算rectSrc和rectDst的X坐标
if (lXOffset <= -lWidth)
{
// X轴方向全部移出可视区域
bVisible = FALSE;
}
else if (lXOffset <= 0)
{
// 移动后,有图区域左上角X坐标为0
rectDst.left = 0;
// 移动后,有图区域右下角X坐标为lWidth - |lXOffset| = lWidth
+ lXOffset
rectDst.right = lWidth + lXOffset;
}
else if (lXOffset < lWidth)
{
// 移动后,有图区域左上角X坐标为lXOffset
rectDst.left = lXOffset;
// 移动后,有图区域右下角X坐标为lWidth
rectDst.right = lWidth;
}
else
{
// X轴方向全部移出可视区域
bVisible = FALSE;
}
// 平移后剩余图像在源图像中的X坐标
rectSrc.left = rectDst.left - lXOffset;
rectSrc.right = rectDst.right - lXOffset;
// 计算rectSrc和rectDst的Y坐标
if (lYOffset <= -lHeight)
{
// Y轴方向全部移出可视区域
bVisible = FALSE;
}
else if (lYOffset <= 0)
{
// 移动后,有图区域左上角Y坐标为0
rectDst.top = 0;
// 移动后,有图区域右下角Y坐标为lHeight - |lYOffset| =
lHeight + lYOffset
rectDst.bottom = lHeight + lYOffset;
}
else if (lYOffset < lHeight)
{
// 移动后,有图区域左上角Y坐标为lYOffset
rectDst.top = lYOffset;
// 移动后,有图区域右下角Y坐标为lHeight
rectDst.bottom = lHeight;
}
else
{
// X轴方向全部移出可视区域
bVisible = FALSE;
}
// 平移后剩余图像在源图像中的Y坐标
rectSrc.top = rectDst.top - lYOffset;
rectSrc.bottom = rectDst.bottom - lYOffset;
// 暂时分配内存,以保存新图像
hNewDIBBits = LocalAlloc(LHND, lLineBytes * lHeight);
if (hNewDIBBits == NULL)
{
// 分配内存失败
return FALSE;
}
// 锁定内存
lpNewDIBBits = (char * )LocalLock(hNewDIBBits);
// 初始化新分配的内存,设定初始值为255
lpDst = (char *)lpNewDIBBits;
memset(lpDst, (BYTE)255, lLineBytes * lHeight);
// 如果有部分图像可见
if (bVisible)
{
// 平移图像
for(i = 0; i < (rectSrc.bottom - rectSrc.top); i++)
{
// 要复制区域的起点,注意由于DIB图像内容是上下倒置的,
第一行内容是保存在最后
// 一行,因此复制区域的起点不是lpDIBBits + lLineBytes * (i + rectSrc.top) +
// rectSrc.left,而是 lpDIBBits + lLineBytes * (lHeight - i - rectSrc.top - 1) +
// rectSrc.left。
lpSrc = (char *)lpDIBBits + lLineBytes * (lHeight - i - rectSrc.top - 1) + rectSrc.left;
// 要目标区域的起点
// 同样注意上下倒置的问题。
lpDst = (char *)lpNewDIBBits + lLineBytes * (lHeight - i - rectDst.top - 1) +
rectDst.left;
// 拷贝每一行,宽度为rectSrc.right - rectSrc.left
memcpy(lpDst, lpSrc, rectSrc.right - rectSrc.left);
}
}
// 复制平移后的图像
memcpy(lpDIBBits, lpNewDIBBits, lLineBytes * lHeight);
// 释放内存
LocalUnlock(hNewDIBBits);
LocalFree(hNewDIBBits);
// 返回
return TRUE;
}
/****************************************************************
****
图像灰度变换之灰级窗的主要原代码: #include "stdafx.h"
#include "cdib.h"
#include "math.h"
#include
#include
using namespace std; #include "GlobalApi.h" 设置灰级窗数值:
/****************************************************************
****
#include "stdafx.h"
#include "DlgEhnLinTrans.h" #ifdef _DEBUG
#define new DEBUG_NEW #undef THIS_FILE
static char THIS_FILE[] = __FILE__; #endif
/****************************************************************
****
CDlgEhnLinTrans::CDlgEhnLinTrans(CWnd* pParent /*=NULL*/)
: CDialog(CDlgEhnLinTrans::IDD, pParent) {
m_nX1 = 0;
m_nX2 = 0;
m_nY1 = 0;
m_nY2 = 0;
}
void CDlgEhnLinTrans::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Text(pDX, IDC_EDIT_LINTRANS_X1, m_nX1);
DDV_MinMaxInt(pDX, m_nX1, 0, 255);
DDX_Text(pDX, IDC_EDIT_LINTRANS_X2, m_nX2);
DDV_MinMaxInt(pDX, m_nX2, 0, 255);
DDX_Text(pDX, IDC_EDIT_LINTRANS_Y1, m_nY1);
DDV_MinMaxInt(pDX, m_nY1, 0, 255);
DDX_Text(pDX, IDC_EDIT_LINTRANS_Y2, m_nY2);
DDV_MinMaxInt(pDX, m_nY2, 0, 255); }
BEGIN_MESSAGE_MAP(CDlgEhnLinTrans, CDialog)
ON_WM_LBUTTONDOWN()
ON_WM_MOUSEMOVE()
ON_WM_LBUTTONUP()
ON_WM_PAINT()
ON_EN_KILLFOCUS(IDC_EDIT_LINTRANS_X1, OnKillfocusEditLintransX1)
ON_EN_KILLFOCUS(IDC_EDIT_LINTRANS_X2, OnKillfocusEditLintransX2)
ON_EN_KILLFOCUS(IDC_EDIT_LINTRANS_Y1, OnKillfocusEditLintransY1)
ON_EN_KILLFOCUS(IDC_EDIT_LINTRANS_Y2, OnKillfocusEditLintransY2)
END_MESSAGE_MAP()
/****************************************************************
****
BOOL CDlgEhnLinTrans::OnInitDialog()
{
CDialog::OnInitDialog(); // 调用默认OnInitDialog函数
CWnd* pWnd = GetDlgItem(IDC_LINTRANS_SHOWCOR); // 获取绘制直方图的标签
pWnd->GetClientRect(m_rectMouse); // 计算接受鼠标事件的有效区域
pWnd->ClientToScreen(&m_rectMouse);
CRect rect;
GetClientRect(rect);
ClientToScreen(&rect);
m_rectMouse.top -= rect.top;
m_rectMouse.left -= rect.left;
m_rectMouse.top += 25; // 设置接受鼠标事件的有效区域
m_rectMouse.left += 10;
m_rectMouse.bottom = m_rectMouse.top + 255;
m_rectMouse.right = m_rectMouse.left + 256;
m_nIsDraging = 0; // 初始化拖动状态
return TRUE;
}
void CDlgEhnLinTrans::OnLButtonDown(UINT nFlags, CPoint point)
{
if(m_rectMouse.PtInRect(point)) // 当用户单击鼠标左键开始拖动
{
CRect rectTemp;
rectTemp.left = m_rectMouse.left + m_nX1 - 2; // 计算点1临近区域
rectTemp.right = m_rectMouse.left + m_nX1 + 2;
rectTemp.top = 255 + m_rectMouse.top - m_nY1 - 2;
rectTemp.bottom = 255 + m_rectMouse.top - m_nY1 + 2;
if (rectTemp.PtInRect(point)) // 判断用户是不是想拖动点1
{
m_nIsDraging = 1; // 设置拖动状态1,拖动点1
::SetCursor(::LoadCursor(NULL, IDC_SIZEALL)); // 更改光标
}
else
{
rectTemp.left = m_rectMouse.left + m_nX2 - 2; // 计算点
2临近区域
rectTemp.right = m_rectMouse.left + m_nX2 + 2;
rectTemp.top = 255 + m_rectMouse.top - m_nY2 - 2;
rectTemp.bottom = 255 + m_rectMouse.top - m_nY2 + 2;
if (rectTemp.PtInRect(point)) // 判断用户是不是想拖动
点2
{
m_nIsDraging = 2; // 设置拖动状态为2,拖动点2
::SetCursor(::LoadCursor(NULL, IDC_SIZEALL)); // 更
改光标
}
}
}
CDialog::OnLButtonDown(nFlags, point); // 默认单击鼠标左键处
理事件
}
void CDlgEhnLinTrans::OnLButtonUp(UINT nFlags, CPoint point)
{
if (m_nIsDraging != 0) // 当用户释放鼠标左键停止拖动
{
m_nIsDraging = 0; // 重置拖动状态
}
CDialog::OnLButtonUp(nFlags, point); // 默认释放鼠标左键处理事件
}
void CDlgEhnLinTrans::OnMouseMove(UINT nFlags, CPoint point)
{
if(m_rectMouse.PtInRect(point)) // 判断当前光标是否在绘制区域
{
if (m_nIsDraging != 0) // 判断是否正在拖动
{
if (m_nIsDraging == 1) // 判断正在拖动点1还是点2
{
if (point.x - m_rectMouse.left < m_nX2) // 判断是否下限<上限
{
m_nX1 = point.x - m_rectMouse.left; // 更改下限
}
else
{
m_nX1 = m_nX2 - 1; // 下限拖过上限,设置为上限-1
point.x = m_rectMouse.left + m_nX2 - 1; // 重设鼠标位置
}
m_nY1 = 255 + m_rectMouse.top - point.y; // 更改Y坐标
}
else
{ // 正在拖动点2
if (point.x - m_rectMouse.left > m_nX1) // 判断是否上限>下限
{
m_nX2 = point.x - m_rectMouse.left; // 更改下限
}
else
{
m_nX2 = m_nX1 + 1; // 下限拖过上限,设置为下限,1
point.x = m_rectMouse.left + m_nX1 + 1; // 重设鼠标位置
}
m_nY2 = 255 + m_rectMouse.top - point.y; // 更改Y坐标
}
::SetCursor(::LoadCursor(NULL, IDC_SIZEALL)); // 更改光标
UpdateData(FALSE); // 更新
InvalidateRect(m_rectMouse, TRUE); // 重绘
}
else
{
CRect rectTemp1;
CRect rectTemp2;
rectTemp1.left = m_rectMouse.left + m_nX1 - 2; // 计算点
1临近区域
rectTemp1.right = m_rectMouse.left + m_nX1 + 2;
rectTemp1.top = 255 + m_rectMouse.top - m_nY1 - 2;
rectTemp1.bottom = 255 + m_rectMouse.top - m_nY1 + 2;
rectTemp2.left = m_rectMouse.left + m_nX2 - 2; // 计算点
2临近区域
rectTemp2.right = m_rectMouse.left + m_nX2 + 2;
rectTemp2.top = 255 + m_rectMouse.top - m_nY2 - 2;
rectTemp2.bottom = 255 + m_rectMouse.top - m_nY2 + 2;
if ((rectTemp1.PtInRect(point)) ||
(rectTemp2.PtInRect(point)))
// 判断用户在点1或点2旁边
{
::SetCursor(::LoadCursor(NULL, IDC_SIZEALL)); // 更
改光标
}
}
}
CDialog::OnMouseMove(nFlags, point); // 默认鼠标移动处理事件
}
void CDlgEhnLinTrans::OnPaint()
{
CPaintDC dc(this); // device context for painting
CString str; // 字符串
CWnd* pWnd = GetDlgItem(IDC_LINTRANS_SHOWCOR);
// 获取绘制坐标的文本框
CDC* pDC = pWnd->GetDC(); // 指针
pWnd->Invalidate();
pWnd->UpdateWindow();
pDC->Rectangle(0,0,330,300);
CPen* pPenRed = new CPen; // 创建画笔对象
pPenRed->CreatePen(PS_SOLID, 2, RGB(255,0,0)); // 红色画笔
CPen* pPenBlue = new CPen; // 创建画笔对象
pPenBlue->CreatePen(PS_SOLID, 1, RGB(0,0, 255)); // 蓝色画笔
CGdiObject* pOldPen = pDC->SelectObject(pPenRed);
// 选中当前红色画笔,并保存以前的画笔
pDC->MoveTo(10,10); // 绘制坐标轴
pDC->LineTo(10,280); // 垂直轴
pDC->LineTo(320,280); // 水平轴
str.Format("0"); // 写坐标
pDC->TextOut(10, 281, str);
str.Format("255");
pDC->TextOut(265, 281, str);
pDC->TextOut(11, 25, str);
pDC->LineTo(315,275); // 绘制X轴箭头
pDC->MoveTo(320,280);
pDC->LineTo(315,285);
pDC->MoveTo(10,10); // 绘制X轴箭头
pDC->LineTo(5,15);
pDC->MoveTo(10,10);
pDC->LineTo(15,15);
pDC->SelectObject(pPenBlue); // 更改成蓝色画笔
str.Format("(%d, %d)", m_nX1, m_nY1); // 绘制坐标值
pDC->TextOut(m_nX1 + 10, 281 - m_nY1, str);
str.Format("(%d, %d)", m_nX2, m_nY2);
pDC->TextOut(m_nX2 + 10, 281 - m_nY2, str);
pDC->MoveTo(10, 280); // 绘制用户指定的变换直线
pDC->LineTo(m_nX1 + 10, 280 - m_nY1);
pDC->LineTo(m_nX2 + 10, 280 - m_nY2);
pDC->LineTo(265, 25);
CBrush brush; // 绘制点边缘的小矩形
brush.CreateSolidBrush(RGB(0,255,0));
CGdiObject* pOldBrush = pDC->SelectObject(&brush); // 选中
刷子
pDC->Rectangle(m_nX1 + 10 - 2, 280 - m_nY1 - 2, m_nX1 + 12, 280
- m_nY1 + 2); // 绘制小矩形
pDC->Rectangle(m_nX2 + 10 - 2, 280 - m_nY2 - 2, m_nX2 + 12, 280
- m_nY2 + 2);
pDC->SelectObject(pOldPen); // 恢复以前的画笔
pDC->MoveTo(10,25); // 绘制边缘
pDC->LineTo(265,25);
pDC->LineTo(265,280);
delete pPenRed; // 删除新的画笔
delete pPenBlue;
}
void CDlgEhnLinTrans::OnKillfocusEditLintransX1() {
UpdateData(TRUE); // 更新
if (m_nX1 > m_nX2) // 判断是否下限超过上限
{
int nTemp = m_nX1; // 互换
m_nX1 = m_nX2;
m_nX2 = nTemp;
nTemp = m_nY1;
m_nY1 = m_nY2;
m_nY2 = nTemp;
UpdateData(FALSE); // 更新
}
InvalidateRect(m_rectMouse, TRUE); // 重绘 }
void CDlgEhnLinTrans::OnKillfocusEditLintransX2() {
UpdateData(TRUE); // 更新
if (m_nX1 > m_nX2) // 判断是否下限超过上限
{
int nTemp = m_nX1; // 互换
m_nX1 = m_nX2;
m_nX2 = nTemp;
nTemp = m_nY1;
m_nY1 = m_nY2;
m_nY2 = nTemp;
UpdateData(FALSE); // 更新
}
InvalidateRect(m_rectMouse, TRUE); // 重绘 }
void CDlgEhnLinTrans::OnKillfocusEditLintransY1() {
UpdateData(TRUE); // 更新
InvalidateRect(m_rectMouse, TRUE); // 重绘 }
void CDlgEhnLinTrans::OnKillfocusEditLintransY2() {
UpdateData(TRUE); // 更新
InvalidateRect(m_rectMouse, TRUE); // 重绘 }
void CDlgEhnLinTrans::OnOK()
{
if (m_nX1 > m_nX2) // 判断是否下限超过上限
{
int nTemp = m_nX1; // 互换
m_nX1 = m_nX2;
m_nX2 = nTemp;
nTemp = m_nY1;
m_nY1 = m_nY2;
m_nY2 = nTemp;
UpdateData(FALSE); // 更新
}
CDialog::OnOK(); // 默认处理事件 }