Linux下的放大镜的设计与实现Word下载.docx
- 文档编号:18343472
- 上传时间:2022-12-15
- 格式:DOCX
- 页数:11
- 大小:24.27KB
Linux下的放大镜的设计与实现Word下载.docx
《Linux下的放大镜的设计与实现Word下载.docx》由会员分享,可在线阅读,更多相关《Linux下的放大镜的设计与实现Word下载.docx(11页珍藏版)》请在冰豆网上搜索。
而Linux系统也只是用了十年时间,就从出现走向了成熟。
计算机行业的更新速度让人震惊。
自1991年Linux系统的出现,它就在桌面系统和服务器中以惊人的速度占据重要地位,体现出系统功能的强大与完善。
Linux系统的高效性和灵活性,使其应用领域十分广泛,因此它被业内人士认为是最有前途的操作系统之一。
更加突出的是,Linux系统在嵌入式行业显示了其极大的优势,开放源码,可移植性好,系统稳定等,赢得众多开发人员的青睐。
目前,比较热门的智能家居设计,就是嵌入式产品的典型。
Linux系统的出现,也是让人相当的称赞。
一位名叫LinusTorvalds的学生,他的想法十分简单,设计一个既有Uinux系统的完整功能,还要能替代Minix的操作系统,由此,诞生了Linux系统。
Linux系统刚刚出现,就受到了开发人员和众多计算机爱好者的喜爱。
Linux系统两个主要原因,导致它受到如此的欢迎,一是软件自由,用户可以按照自身的需要裁剪源代码,设计出自己需要的程序来。
二是它拥有Unix系统的完整功能,即使是以前没有使用过Linux系统,但是只要是接触过Unix系统,就能很容易操作Linux平台。
Linux系统的一大特点是多平台性,也就是说Linux系统可以在多种硬件平台运行上,比如x86、SPARC、680x0[1]等处理器上。
可以看出,Linux系统有着诸多的优势和良好的发展前景,难怪有那么多的开发人员和厂商投身于Linux领域的开发和生产中。
1.2研究Linux系统下放大镜设计的目的和意义
图像数据的处理,是本次设计的关键所在,也是放大镜实现放大功能的前提。
通过对放大镜实现功能的具体分析,选择了两种比较适合的插值算法。
一种是最临近插值算法,另外一种是双线性插值算法[12]。
这两种算法各有自身的优点,前者是处理数据的速度比较快,后者是数据处理的结果比较准确。
因此,根据不同的需求,设计出两种不同类型的放大镜,一次满足用户的放大需求。
此次的放大镜设计,是对Linux系统更加深入的学习和理解,掌握Linux系统的开发方法,对于今后自身的开发技术的提高很有帮助。
在Linux系统中,与Windows系统最大的区别是一切皆是文件,对于系统内核来说,无论是软件、进程等,都被看作是文件。
总的来看,使用Linux的用户可以按照自己的意愿修改源码,对于从事开发开发行业的人来说,有着极大的好处。
学习Linux系统,使得自己对操作系统,开发工具,开发语言等都会有这更加深入的了解,对今后的开发工作十分有促进意义。
因此,学习在Linux系统下开发应用程序,一方面是对系统、语言等的进一步研究,另一方面也是把自己所学到的知识运用到开发中,检验自身的学习成果。
2.放大镜设计的需求分析
2.1Linux系统的概况
开源软件的影响力在不断增强,在世界范围内,Linux系统于桌面、服务器、行业制定等领域得到了长久的发展,特别在服务器行业,更是占据重要地位。
Linux内核2.6的出现,展现了Linux系统的重大进步,是其走向成熟和稳定的标识。
如今,虽然Linux系统版本繁多,但是不同版本内核是相同的,这也是Linux实行标准化、互换性的基础。
在服务器方面,由于IBM和因特尔等公司的鼎力支持,Linux系统取得了长期有效的发展。
电子商务在近年来的发展中不断的扩大,越来越多的用户和厂商开始重视Linux系统的桌面技术。
目前,比较有开发价值的桌面技术是:
3D桌面,桌面搜索技术,桌面友好性。
不得不承认,Linux系统正在逐步走向计算机中的各个领域,以其独特的优势,占据着主导地位。
2.2需要的技术支持
此次开发,使用的开发工具是跨平台开发框架Qt。
Qt提供了一种安全的类型称为信号与槽机制(signals/bits)[11],用它代替了callback,达到了安全传递信号的功能。
Qt的专注点在于C++图形界面开发,它的优点在于面向对象、跨平台性等。
Qt支持Windows,Linux,SCO等众多的操作系统,体现了其良好的跨平台的特性。
大量的API文档,丰富的C++类包,这是Qt开发的优势所在,也是开发人员迫切需要的。
开发人员可以从文档中了解Qt技术的使用方法,使用已存在的C++类,来简化开发过程。
像GoogleErath(三维地图虚拟软件)、stellarium(天文学自由软件)等,都是用Qt开发出来的。
使用QtCreator[10]作为此次开发的工具,对于了解Qt的作用,开发的流程,以及Qt中工具的使用,很有帮助。
使用Qt开发,利用Qt自身优势,开发出一款满意的放大镜程序。
2.3实现功能的划分
此次设计,把放大镜程序分成了两个部分,一个是“圆形”,一个是“方形”。
所谓“圆形”和“方形”是按照最终设计结果来命名的。
“圆形”是指模拟真实的放大镜,设计出能够即时放大文字或图片的程序,此窗体的外观和普通放大镜一样,因此称为“圆形”。
“方形”放大镜,实际上是一个方形窗体,窗体悬浮在桌面上,窗体中显示的内容随着鼠标位置的不同而改变。
之所以分为“圆形”和“方形”,是从算法效率上考虑。
最临近点插值算法运行效率高于双线性插值算法,但是其放大的图片不如后者清晰。
因此,用前一种插值算法来实现“圆形”放大,就是即时放大功能,用后一种插值算法来实现“方形”放大,即有效放大。
3.放大镜的概要设计
3.1功能设计的概述
放大镜的设计,实现的功能是放大桌面某一部分的图片或者文字,能够让使用者观察到计算机屏幕中细微的图像。
具体的实现原理是,获取鼠标所在位置的图像,并把图像数据放到缓存中[4],然后利用缓存中的数据,通过相应的放大函数处理数据使得图片放大,最后显示到设计好的窗体中。
此次的放大镜设计,可以有两种划分模式[6],一个是按照功能划分,那么可以划分成三个模块:
图像数据采集模块、图像数据处理模块、图像数据输出模块。
系统功能划分如图3.1所示。
如果是按照放大镜实现放大的技术上划分,可以分成两个部分,即“圆形”部分和“方形”部分。
在此,我选择了使用第一种方式来描述,因为它更加贴近软件开发的设计模式。
图3.1系统功能模块划分图
3.2模块划分
3.2.1图像数据采集模块
此模块的功能是获取当前屏幕任意区域的图像数据。
程序设计的大概流程如下:
(1)建立起数据连接,开启数据集;
(2)初始化列表,使得列表的显示条件符合数据记录的要求
(3)遍历数据集中的数据,把数据加到列表中
(4)断开数据集,断开数据连接
在这图像数据的采集过程中,使用到的方法如下:
QWidget*desktop=reinterpret_cast<
QWidget*>
(QApplication:
:
desktop());
mCapturePixmap=QPixmap:
grabWindow(desktop->
winId());
这里reinterpret_cast<
desktop())方法的作用是定义了一个指向流的指针[5],管理图形界面中用户应用控制流。
使用QPixmap类中grabWindow()方法读取图像的数据流。
调用这两种方法,获取指定图片的数据,保存在临时变量中,用于对数据的进一步处理。
3.2.2图像数据处理模块
按照要求处理得到的图像数据,实现不同放大。
选择什么样的放大方法,如何放大,这个就决定了图片在最后放大后时质量,以及放大的形式的不同。
但是这两种方法有着共同的功能,那就是获取图像数据,进行放大处理。
需要具体分析的是,两种放大方法的算法设计。
第一种是最临近点插值算法:
最临近点插值算法是一种简单而有快速的插值算法。
通过把目标图片上的未知像素点,映射到原始数据上,和原始影像上4个与其相邻的像素点进行比较,把最接近未知像素点的值作为目标图片中未知像素点的值。
如图3.2所示:
p最接近D点,于是p的像素值就是D点像素值
图3.2最临近点插值算法示意图
最临近点插值算法的公式如下:
(1)
公式
(1)中,表示的是输出图像中坐标是位置的像素点颜色值。
表示的是输入图像中坐标是处的像素点颜色值。
第二种是双线性插值算法:
使用双线性插值是放大后的图片质量比较高,就是计算量有点大。
不过,与最临近插值算法相比,不会出现像素点不连续的状况。
图3.3是其示意图:
图3.3双线性插值算法示意图
其公式如下:
(2)
在该公式中,i,j代表了像素点的位置,比如原图中(i,j)的像素值用f(i,j)来表示。
3.2.2图像数据输出模块
输出模块的作用比较简单,主要的作用就是实现放大后的数据流输出的功能。
该模块使用了独立的输出方法,即重写了QPainter类中的PaintEvent()方法,绘画出放大后的图片。
这样写的好处是,可以根据自身需要,随时调用绘画方法,显示放大后的图像。
4.放大镜的详细设计
4.1详细设计的概述
之前,已经讲述了论文设计的实现方法,接下来要做的是进行详细设计,最终完成放大镜的设计工作。
首先,先看一下放大镜设计的主界面[9],如图4.1所示。
图4.1放大镜的主界面
在这个界面中,有两个按钮,命名是“圆形”,“方形”。
若点击了“圆形”按钮之后,出现形状是圆形的放大镜,这个就是那个简易放大镜。
若是点击了“方形”按钮之后,出现的方大镜是方形的,这个就是那个清晰放大镜。
需要注意的是,这两个放大镜并不能同时出现,一次只能出现一个。
还有就是,子窗口的启动运用到了进程QProcess类。
此时,子窗口运行于独立的进程中,如果只是简单的通过关闭按钮关闭子窗口,那么该进程并没有结束,最后可能会成为孤儿进程[3]。
因此,为了避免此类现象的发生,采用了主动杀死进程的方法。
当用户希望退出当前子窗口时,再点击一下父窗口中的按钮,那么子窗口进程将会被结束掉,子窗口将会退出。
4.2采集模块的设计
采集模块主要的作用是采集鼠标所在处的屏幕图像数据。
实现方式如下面所给的代码:
voidMagnifierWidget:
moveEvent(QMoveEvent*event)
{
//获取鼠标所在位置的图片信息
QPixmapdrawpix=mCapturePixmap.copy(pos().x(),pos().y(),width(),height());
source=drawpix.toImage();
//把图片转换成QImage形式
dest=source;
mFilter->
filter(source,dest,source.rect());
mDraw->
repaint();
//重绘图片
returnQWidget:
moveEvent(event);
//返回鼠标点击事件
}
该方法的调用是在数据连接已经建立的基础上使用的。
该方法在获得图像数据后,首先做的事情是把图像的格式进行转化,把它转化成QImage形式,接着调用mFilter对象中的filter()方法,是实现图像数据的放大处理。
4.3处理模块的设计
图像数据处理模块可以说此次放大镜设计的核心部分,它实现了两种不同的放大功能。
按照用户不同的需求,采用不同的放大算法执行图片放大。
“圆形”部分:
在这个部分里,使用的是最临近点插值算法,满足用户即时放大的需求。
该插值算法的优点在运行效率快,但是缺点也很明显,放大后的图片有的地方像素点不连续,清晰度不是很高。
其中,主要的实现方法如下:
boolMagnifierFilter:
filter(constQImage&
source,QImage&
dest,QRectregion)
for(inti=region.left();
i<
region.right();
i++)
{
for(intj=region.top();
j<
region.bottom();
j++)
intx=mMatrixX->
getData(i,j);
inty=mMatrixY->
//设置(i,j)的像素点
dest.setPixel(i,j,source.pixel(x,y));
}
}
returntrue;
上述方法实现的功能是调用最临近点插值算法的方法函数,通过索引(x,y)把源图片中相应坐标处的像素点放置到目标图像中,实现图像的放大。
而其中最临近点插值算法的实现方法的核心代码[7]展示如下,
for(inth=0;
h<
mHeight;
h++)
intposition=h*mWidth;
tmpProgress=qreal(h+1)/(qreal)mHeight;
if(tmpProgress<
FloorProgress||\
tmpProgress>
UpProgress)
progressY=mEasingCurve.valueForProgress(tmpProgress);
valuey=mHeight*progressY;
else
progressY=(progressDived)*\
(tmpProgress-FloorProgress)+progressFromFloor;
for(intw=0;
w<
mWidth;
w++)
tmpProgress=qreal(w+1)/(qreal)mWidth;
FloorProgress||tmpProgress>
UpProgress){
progressX=mEasingCurve.valueForProgress(tmpProgress);
valuex=mWidth*progressX;
progressX=(progressDived)*\
(tmpProgress-FloorProgress)+progressFromFloor;
dataX[position+w]=valuex;
dataY[position+w]=valuey;
“方形”部分:
在此部分中,利用双线性插值算法,实现图像的放大要求。
由于双线性插值算法计算时间长,所以满足不了即时性的要求。
但是,该算法放大的图片清晰度高,能够观察细小的变化。
该算法实现的核心代码如下,
voidPicZoom_Bilinear2(constTPixels32Ref&
Dst,constTPixels32Ref&
Src)
if((0==Dst.width)||(0==Dst.height)
||(0==Src.width)||(0==Src.height))return;
longxrIntFloat_16=((Src.width)<
<
16)/Dst.width+1;
longyrIntFloat_16=((Src.height)<
16)/Dst.height+1;
constlongcsDErrorX=-(1<
15)+(xrIntFloat_16>
>
1);
constlongcsDErrorY=-(1<
15)+(yrIntFloat_16>
longdst_width=Dst.width;
//y0+y*yr>
=0;
y0=csDErrorY=>
y>
=-csDErrorY/yr
longborder_y0=-csDErrorY/yrIntFloat_16+1;
if(border_y0>
=Dst.height)border_y0=Dst.height;
longborder_x0=-csDErrorX/xrIntFloat_16+1;
if(border_x0>
=Dst.width)border_x0=Dst.width;
//y0+y*yr<
=(height-2)=>
y<
=(height-2-csDErrorY)/yr
longborder_y1=(((Src.height-2)<
16)-csDErrorY)/yrIntFloat_16+1;
if(border_y1<
border_y0)border_y1=border_y0;
longborder_x1=(((Src.width-2)<
16)-csDErrorX)/xrIntFloat_16+1;
if(border_x1<
border_x0)border_x1=border_x0;
Color32*pDstLine=Dst.pdata;
longSrc_byte_width=Src.byte_width;
longsrcy_16=csDErrorY;
longy;
for(y=0;
y<
border_y0;
++y)
longsrcx_16=csDErrorX;
for(longx=0;
x<
dst_width;
++x)
Bilinear2_Border(Src,srcx_16,srcy_16,&
pDstLine[x]);
//border
srcx_16+=xrIntFloat_16;
srcy_16+=yrIntFloat_16;
((UInt8*&
)pDstLine)+=Dst.byte_width;
for(y=border_y0;
border_y1;
++y)
longx;
for(x=0;
border_x0;
//border
unsignedlongv_8=(srcy_16&
0xFFFF)>
8;
Color32*PSrcLineColor=
(Color32*)((UInt8*)(Src.pdata)+Src_byte_width*(srcy_16>
16));
for(longx=border_x0;
border_x1;
Color32*PColor0=&
PSrcLineColor[srcx_16>
16];
Color32*PColor1=(Color32*)((UInt8*)(PColor0)+Src_byte_width);
Bilinear2_Fast(PColor0,PColor1,
(srcx_16&
8,v_8,&
for(x=border_x1;
B
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Linux 放大镜 设计 实现