抓图软件课程设计屏幕截图软件设计.doc

上传人:仙人指路1688 文档编号:2884864 上传时间:2023-03-01 格式:DOC 页数:10 大小:87.50KB
返回 下载 相关 举报
抓图软件课程设计屏幕截图软件设计.doc_第1页
第1页 / 共10页
抓图软件课程设计屏幕截图软件设计.doc_第2页
第2页 / 共10页
抓图软件课程设计屏幕截图软件设计.doc_第3页
第3页 / 共10页
抓图软件课程设计屏幕截图软件设计.doc_第4页
第4页 / 共10页
抓图软件课程设计屏幕截图软件设计.doc_第5页
第5页 / 共10页
点击查看更多>>
资源描述

《抓图软件课程设计屏幕截图软件设计.doc》由会员分享,可在线阅读,更多相关《抓图软件课程设计屏幕截图软件设计.doc(10页珍藏版)》请在三一办公上搜索。

1、屏幕截图软件设计杨金(西北农林科技大学信息工程学学院计算机科学与技术2002级3班 陕西杨凌 712100 )摘要: 本文阐述 VC+实现屏幕截图功能的原理和具体设计步骤,所实现的这个抓图软件可以截取整个屏幕,截取指定的窗口,并将截取到的图像以bmp文件形式保存到指定的路径下。技术重点在鼠标在屏幕上的准确定位;如何获取抓图的窗口句柄;如何对抓到的图片进行保存的问题。技术难点在如何将所抓取的屏幕窗口保存为磁盘BMP文件形式。关键词:屏幕截图;BMP位图;设备环境(DC)1 引言在我们的日常上网活动当中比如看电影、玩游戏、做图等等会对一些画面特别喜欢!但是却没有办法将这些画面以图片形式保存下来,真

2、是犹如“水中月,镜中花”看得到却得不到。由于QQ的出现,曾改变了几亿人的交流生活方式,它的里面嵌入的任意截图功能,更是为人们的生活增添了无限的欢愉和快乐,通过截图自己可以将最喜欢的游戏画面,最喜欢的电影画面,以图片形式保存,可以及时的发给好友共享,给我们带来了意想不到的帮助和惊喜。另外系统的功能强大的截图软件在社会建设的各个领域都到了施展空间,为人们的工作生活创造了极大的方便,解决了许多棘手难题。可以说呀抓图软件有很广阔的应用前景,虽然它不算是很庞大的系统软件,但是其它的大型的主流系统软件能够嵌入抓图的功能,必将受到极大的欢迎和青睐。所以在此次软件课程设计当中,我选择了用VC制作屏幕截图的软件

3、,实现截取指定窗口,整个屏幕的功能,并且将截取的图形以BMP文件形式存放在指定路径的磁盘当中。本文将系统介绍截图软件的设计原理,设计步骤,设计方法,和运用的重点技术。2 实现基本原理和运用相关技术抓图软件基本原理就是把屏幕上所抓取的图像复制到内存中,并最后将内存中的图像内容以位图文件形式保存到磁盘当中。在这此软件设计当中,如果用户将鼠标左键按住不放,则开始抓取图片,此时隐藏程序窗口,以免影响在抓取时的“视野”,接着装入“魔法棒”鼠标,开始追踪鼠标的移动,然后获得鼠标所在处的窗口句柄,取得屏幕的设备环境句柄,以便在屏幕的任何位置绘图。接下来建立一红色的画笔,得到鼠标所在处的窗口的区域,在鼠标所在

4、处的窗口四周画一红色的矩形,做为选定时的提醒。当鼠标左键释放的时候得到鼠标所在处的窗口的区域宽、高,然后建立一个屏幕设备环境句柄和与屏幕设备环境句柄兼容、与鼠标所在处的窗口的区域等大的位图,把新位图选到内存设备描述表中,最后把屏幕设备描述表拷贝到内存设备描述表中,终止鼠标捕获,恢复窗口显示模式。那么最后要作的工作就是写一个位图保存函数将内存当中的窗口图片信息以位图形式保存到指定磁盘当中。在整个程序当中要用到大量的函数:比如申请内存空间用于存放位图文件 GlobalAlloc(GHND,FileLength); 位图文件读入所申请内存空间中LoadFileToMemory( mpBitsSrc,

5、mFileName); 在OnPaint等函数中用创建显示用位图;用CreateDIBitmap()创建显示用位图;用CreateCompatibleDC()创建兼容DC, 用SelectBitmap()选择显示位图; 用BitBlt或StretchBlt等函数显示位图 ; 用DeleteObject()删除所创建的位图;程序中还会用到许多关键函数在这里不在详细叙述,其功能用法可以参照MSDN。屏幕抓图程序的关键有两点:一是应该知道鼠标在屏幕上有准确位置;二是应该知道欲抓图的窗口句柄;三是如何对抓到的图片进行保存的问题。对于问题一,很简单,利用SetCapture函数便能够追踪鼠标的移动(包括

6、在屏幕抓图程序窗口之外的窗口)。对于问题二,这时会用到一个平时我们不常用的函数:WindowFromPoint,其函数用法如下:HWND WindowFromPoint POINT Point; /坐标;这个函数能够找出鼠标当前位置所对应的窗口句柄。具体用法可以参见MSDN,这里不做详细叙述。在选择抓图窗口时,鼠标的在位置的窗口都会出现加粗的有色边框,以提醒目前所选择的窗口,这个功能实现起来有些复杂,它的代码如下:POINT pt5; pt0 = CPoint(rectCapture.left, rectCapture.top); pt1 = CPoint(rectCapture.right,

7、rectCapture.top); pt2 = CPoint(rectCapture.right,rectCapture.bottom); pt3 = CPoint(rectCapture.left, rectCapture.bottom); pt4 = CPoint(rectCapture.left, rectCapture.top);在GDI中,最常见的一个概念就设备环境(DC),每一个窗口都相应的具有自己的DC。如果能够调用到窗口的DC,那么,我们便能够在窗口上的任何位置绘图。然而,在屏幕抓图程序中,由于用户所选择的窗口是不固定的,所以,要想得到鼠标所在处的窗口的DC,不是很容易。但是能

8、够随心所欲地在屏幕上进行绘图却又不仅限于特定的窗口,GetDC能够做到这点! GetDC的函数申明:HDC GetDC( HWND hWnd),hWnd是DC对应的窗口句柄,当hWnd为空时,该函数返回的是整个屏幕的设备环境句柄!这就意味着我们可以在屏幕上进行任意绘图。在鼠标所在处的窗口进行绘图时,绘图本身的目的只是为了提醒用户目前所选择的窗口,所以,在进行绘图时,必须得保证不会破坏窗口原有的画面。这点很好办,将窗口的DC绘图模式设为R2_NOTXORPEN(将画笔颜色与屏幕颜色进行异或后,再将屏幕颜取反),这样,在同一个地方进行两次绘图后(对同一像素进行两次异或运算,像素值并不会发生变化),

9、窗口的画面并不会发生任何变化。以上就是此次截图软件设计当中运用的相关技术和设计实现原理。3 软件详细设计31建立基于对话框的工程文件启动Visual C+,生成一个基于对话框的工程,工程名为“Capture”. 然后准备好一个外形为细长矩形的光标文件(*.cur),将之引入资源管理器(IDC_CAMERA)。接着在CCaptureDlg类中加入两个全局变量:HWND hwndCapture; CRect rectCapture; UINT nFlags;CPoint point;LPCTSTR lpFileName;HBITMAP hBitmap;32添加消息响应函数然后通过类向导加入对WM_

10、MOUSEMOVE及WM_LBUTTONUP事件的响应函数,添加WM_MOUSEMOVE事件的响应函数代码该函数主要实现的功能:鼠标左键按住不放,则开始抓取图片,此时隐藏程序窗口,以免影响在抓取时的“视野”,接着装入“魔法棒”鼠标,开始追踪鼠标的移动,然后获得鼠标所在处的窗口句柄,取得屏幕的设备环境句柄,以便在屏幕的任何位置绘图。接下来建立一红色的画笔,得到鼠标所在处的窗口的区域,在鼠标所在处的窗口四周画一红色的矩形,做为选定时的提醒。void CCaptureDlg:OnMouseMove(UINT nFlags, CPoint point) /如果用户将鼠标左键按住不放,则开始抓取图片 i

11、f(nFlags=MK_LBUTTON) /隐藏程序窗口,以免影响在抓取时的“视野” ShowWindow(SW_HIDE); /装入“魔法棒”鼠标,开始追踪鼠标的移动 HCURSOR cur=LoadCursor(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDC_CAMERA ); SetCursor(cur); SetCapture(); /获得鼠标所在处的窗口句柄 ClientToScreen(&point); hwndCapture=(HWND):WindowFromPoint(point); /取得屏幕的设备环境句柄,以便在屏幕的任何位置绘图 HD

12、C hDC=:GetDC(NULL); /建立一红色的画笔 HPEN hPen =CreatePen(PS_INSIDEFRAME,6, RGB(255,0,0); /将绘图模式设为R2_NOTXORPEN,在绘图时可以不破坏原有的背景 int nMode =SetROP2(hDC, R2_NOTXORPEN); HPEN hpenOld= (HPEN)SelectObject(hDC, hPen); /得到鼠标所在处的窗口的区域 :GetWindowRect(hwndCapture,&rectCapture); /在鼠标所在处的窗口四周画一红色的矩形,做为选定时的提醒 POINT pt5;

13、pt0 = CPoint(rectCapture.left, rectCapture.top); pt1 = CPoint(rectCapture.right,rectCapture.top); pt2 = CPoint(rectCapture.right,rectCapture.bottom); pt3 = CPoint(rectCapture.left, rectCapture.bottom); pt4 = CPoint(rectCapture.left, rectCapture.top); :Polyline(hDC,pt,5); /延时后再重绘红色的矩形,这样就不会破坏原有内容 Sle

14、ep(100); :Polyline(hDC,pt,5); :SelectObject(hDC,hpenOld); :ReleaseDC(NULL,hDC); CDialog:OnMouseMove(nFlags, point);添加WM_LBUTTONUP事件的响应函数代码:该函数主要实现当鼠标左键释放的时候得到鼠标所在处的窗口的区域宽、高,然后建立一个屏幕设备环境句柄和与屏幕设备环境句柄兼容、与鼠标所在处的窗口的区域等大的位图,把新位图选到内存设备描述表中,最后把屏幕设备描述表拷贝到内存设备描述表中,终止鼠标捕获,恢复窗口显示模式。void CCaptureDlg:OnLButtonUp(

15、UINT nFlags, CPoint point) /得到鼠标所在处的窗口的区域宽、高 int nWidth=rectCapture.Width(); int nHeight=rectCapture.Height(); HDC hdcScreen, hMemDC; HBITMAP hOldBitmap; /建立一个屏幕设备环境句柄 hdcScreen = CreateDC(DISPLAY, NULL, NULL, NULL); hMemDC = CreateCompatibleDC(hdcScreen); /建立一个与屏幕设备环境句柄兼容、与鼠标所在处的窗口的区域等大的位图 hBitmap

16、= CreateCompatibleBitmap(hdcScreen, nWidth, nHeight); / 把新位图选到内存设备描述表中 hOldBitmap =(HBITMAP)SelectObject(hMemDC, hBitmap); / 把屏幕设备描述表拷贝到内存设备描述表中 BitBlt(hMemDC,0,0,nWidth,nHeight,hdcScreen,rectCapture.left,rectCapture.top,SRCCOPY); /取回鼠标所在处的窗口屏幕位图的句柄 hBitmap =(HBITMAP)SelectObject(hMemDC, hOldBitmap)

17、; DeleteDC(hdcScreen); DeleteDC(hMemDC); MessageBox(屏幕内容已经剪切获得,请单击对话框菜单按纽保存为BMP文件!); /终止鼠标捕获 ReleaseCapture(); /恢复窗口显示模式 ShowWindow(SW_NORMAL); CDialog:OnLButtonUp(nFlags, point);33将抓取的窗口图片保存为位图文件存取设计保存函数SaveBitmapToFile(HBITMAP hBitmap, LPCTSTR lpFileName),并且在前面对话框类里面进行函数声明。此函数是整个软件设计当中的技术难点,要特别对BM

18、P位图文件非常熟悉,BMP文件由文件头、位图信息头、颜色信息和图形数据四部分组成。BMP文件头数据结构含有BMP文件的类型、文件大小和位图起始位置等信息。位图文件的类型,必须为BM位图文件的大小,以字节为单位,位图文件保留字,必须为0位图数据的起始位置,以相对于位图文件头的偏移量表示,以字节为单位。BMP位图信息头数据用于说明位图的尺寸等信息。在typedef struct tagBITMAPINFOHEADER结构当中DWORD biSize表示本结构所占用字节数;LONGbiWidth表示位图的宽度;以像素为单位LONGbiHeight表示位图的高度,以像素为单位WORD biPlanes

19、表示目标设备的级别,必须为1;WORD biBitCount表示每个像素所需的位数,必须是1(双色),4(16色),8(256色)或24(真彩色)之一;DWORD biCompression; 表示位图压缩类型,必须是 0(不压缩), 1(BI_RLE8压缩类型)或2(BI_RLE4压缩类型)之一,DWORD biSizeImage表示位图的大小,以字节为单位;LONGbiXPelsPerMeter表示位图水平分辨率,每米像素数;LONGbiYPelsPerMeter表示位图垂直分辨率,每米像素数;DWORD biClrUsed表示位图实际使用的颜色表中的颜色数;DWORD biClrImpo

20、rtant表示位图显示过程中重要的颜色数。颜色表用于说明位图中的颜色,它有若干个表项,每一个表项是一个RGBQUAD类型的结构,定义一种颜色。RGBQUAD结构的定义如下: 在typedef struct tagRGBQUAD 中BYTErgbBlue表示 蓝色的亮度(值范围为0-255);BYTErgbGreen表示绿色的亮度(值范围为0-255);BYTErgbRed表示 红色的亮度(值范围为0-255);BYTErgbReserved表示 保留,必须为0。颜色表中RGBQUAD结构数据的个数有biBitCount来确定:当biBitCount=1,4,8时,分别有2,16,256个表项;

21、当biBitCount=24时,没有颜色表项。位图信息头和颜色表组成位图信息,BITMAPINFO结构定义如下:typedef struct tagBITMAPINFO BITMAPINFOHEADER bmiHeader; / 位图信息头RGBQUAD bmiColors1; / 颜色表 BITMAPINFO;位图数据记录了位图的每一个像素值,记录顺序是在扫描行内是从左到右,扫描行之间是从下到上。位图的一个像素值所占的字节数: 当biBitCount=1时,8个像素占1个字节;当biBitCount=4时,2个像素占1个字节;当biBitCount=8时,1个像素占1个字节;当biBitCo

22、unt=24时,1个像素占3个字节;Windows规定一个扫描行所占的字节数必须是 4的倍数(即以long为单位),不足的以0填充, 一个扫描行所占的字节数计算方法: DataSizePerLine= (biWidth* biBitCount+31)/8表示一个扫描行所占的字节数; DataSizePerLine= DataSizePerLine/4*4表示字节数必须是4的倍数 ,位图数据的大小(不压缩情况下):DataSize= DataSizePerLine* biHeight; 在SaveBitmapToFile()当中首先定义调色板大小,位图中像素字节大小 ,位图文件大小,写入文件字节

23、数,位图属性结构,位图文件头结构,位图信息头结构,指向位图信息头结构定义文件,分配内存句柄,调色板句柄,计算位图文件每个像素所占字节数,计算调色板大小。计算调色板大小,设置位图信息头结构,为位图内容分配内存,处理调色板,恢复调色板,创建位图文件,设置位图文件头,写入位图文件头,写入位图文件其余内容,最后清除返回。这样此函数就实现了将内存中的屏幕图像数据保存为位图文件形式,它的具体实现代码限于篇幅在这里就不多做介绍了,如果要想详细查看此函数的编写代码,可以在程序文件当中查看。34软件界面设计和其它相关功能设计由于本软件是基于对话框的工程,其界面相对比较单一简单,那么为了使得界面比较漂亮美观,我特

24、别进行了对话框的渐变色设计,使界面有梦幻般的感觉。对话框的渐变色效果是在OnPaint()函数中实现的 ,具体实现细节在这里不多做描述了。在软件设计的最后收尾阶段,实现文件的退出菜单功能设计。图1是该抓图软件的运行界面图形。 (图1)35软件运行功能测试图启动工程执行程序,出现图1程序界面时,用鼠标按下左键,程序界面便隐藏,于是拖动鼠标开始屏幕抓图。当鼠标左键释放后,程序会弹出一个MessageBox对话框来提醒您已经抓取了指定窗口的图片请单击对话框菜单按钮保存为指定磁盘路径的BMP文件,接下来程序窗口出现,最后点击菜单按钮保存抓取的窗口图片。图2就是抓取的全屏位图。 (图2)此抓图软件不仅仅

25、可以抓取全屏图案,还可以抓取任意指定窗口的图形。图3是 抓取指定小窗口的BMP图片。(图3)当抓图结束后,可以单击界面上的菜单退出按钮安全退出,此时程序又会弹出一个MessageBox对话框提醒您是否确定要退出程序。通过大量的调试和运行,该抓图软件运行稳定,抓取保存速度比较快,整体性能比较理想。完成了任意指定窗口的界面截取功能及保存功能。4 存在问题和改进意见在此次屏幕截图软件设计当中主要面对三个问题,一是如何知道鼠标在屏幕上的准确位置;二是如何知道欲抓图的窗口句柄;三是如何对抓到的图片进行保存的问题。对于问题一,很简单,利用SetCapture函数便能够追踪鼠标的移动,包括在屏幕抓图程序窗口

26、之外的窗口。应该注意的是,SetCapture的具体功能并不像MSDN中所说的那样:调用SetCapture一次直到使用ReleaseCapture终止鼠标捕获前都会起到对鼠标的捕获作用,实际上,在使用过程中,就会发现,在进行了一次鼠标捕获之后,SetCapture便失去了作用,这可能是SetCapture函数的一个Bug。所以,在编程时,要不断地调用SetCapture函数,以保证SetCapture能够对鼠标进行正确无误的捕获。对于问题二,这时会用到一个平时我们不常用的函数:WindowFromPoint,这个函数能够找出鼠标当前位置所对应的窗口句柄。问题最多当要属问题三:如何对抓到的图片

27、进行保存且保存为指定位置的bmp文件,这个是整个程序设计当中的难点也是最麻烦的出了很多棘手的问题,由于需要设计一个这样的保存函数,限于自身水平就参考了网上同仁编写的这种功能的函数,于是拿到自己的程序中调用此函数便陷入了尴尬的境地,首先是出现了二三十处语法错误经过耐心修改全部搞定,但是执行程序,单击保存按钮却无法进行保存,一运行会发出错误报告然后自动退出,经过确定是程序逻辑错误,后经过调试是应为在写这个函数的时候,一个参数有问题,是因为该参数是在前面的一个函数中定义过且为私有变量,后面的函数需要调用这个参数,来获取屏幕位图窗口句柄,那么这个参数就需要设置为全局变量,在这里我就犯了这个低级错误。接

28、着执行程序抓图保存,但是令人惊讶的是机子接近崩溃的边缘,运行比“蜗牛”还慢,等大约67分钟后,一切才恢复正常,最后到保存的指定文件中去查看所保存的抓取图片,让人吃惊的是保存的图片大小为655M,怪不得执行程序后会那么慢,经过分析问题出在,设置保存为BMP文件得时候,抓取窗口得长宽大小在函数SaveBitmapToFile()中并没有获得,那么程序运行得时候就任意设置了一个很大得窗口尺寸,才使得所保存得图片大得惊人。经过龙满生老师得细心指导和调试解决了这个问题。但是又有令人郁闷得问题出现了,拿就是所保存得图片大小合适是所抓取窗口的大小,但是图片一片漆黑!龙满生老师说肯定是因为所抓取的图片数据没有

29、获得,用DEBUG设置断点调试明显显示GetDIBits()的数据值为0,但是始终搞不清楚为什么所获得的位图数据值是零,龙满生老师细心的帮我分析,最后才确定出罪魁祸首是DeleteDC(hDC);该函数用错了位置,它在GetDIBits()函数调用之前便调用了那么当然获取的位图数据为零了,于是调整DeleteDC(hDC)为在GetDIBits()函数调用之后调用,终于解决了这个问题。那么到最后该软件就算大功告成了。 该软件特别要改经的地方那就是能够像QQ抓图那样任意拖动鼠标,截取任意大小的图片,并且所见即所抓,不管它是什么东东,游戏画面也好,电影画面也好,FLANSH,静态图片等等,像怎么抓

30、就怎么抓。但是限于自身能力有限还有时间的关系,这些更棒功能等以后再实现吧5 结束语 在此论文当中主要介绍 VC+实现屏幕截图功能的实现基本原理和运用的相关技术详细介绍了软件的具体设计步骤,所实现的这个抓图软件可以截取整个屏幕,截取指定的窗口,并将截取到的图像以bmp文件形式保存到指定的路径下。技术重点在鼠标在屏幕上的准确定位;如何获取抓图的窗口句柄;如何对抓到的图片进行保存的问题。技术难点在如何将所抓取的屏幕窗口保存为磁盘BMP文件形式。 在整个设计当中要运用大量的图形操作函数,特别是在设计保存功能的时候,要对位图文件结构有相当深刻的了解,通过此次设计自己掌握了很多技术如:追踪鼠标的移动,如何

31、获得鼠标所在处的窗口句柄,如何取得屏幕的设备环境句柄得到鼠标所在处的窗口的区域宽、高,如何建立一个屏幕设备环境句柄和与屏幕设备环境句柄兼容、与鼠标所在处的窗口的区域等大的位图,如何把新位图选到内存设备描述表中,如何把屏幕设备描述表拷贝到内存设备描述表中等等。最后要特别感谢龙满生老师,在这两个礼拜的软件设计当中,龙满生老师作为我的导师给予了我巨大的帮助和指导,自己在这个过程当中学会了很多很多东西,比如如何分析程序出错的原因,如何解决问题的方法,特别是我感受到了要想作为一名好的编程人员所应具备的素质,通过老师的指导我还领会了DEBUG断点调试的妙用,从这里我更深入的理解了程序运行的机制和参数数据间

32、的传递以及函数的相互调用。同时增强了自己的编程能力和一些作为编程人员所因具有的耐性和仔细,体会到了沟通协作的重要性,总之在这两个礼拜的软件课程设计当中自己学到了很多很多。 参考文献1何东健. 数字图像处理. 西安:西安电子科技大学出版社,20032杨永国.Visual C+ 6.0实用教程. 北京:清华大学出版社,20043张力. Visual C+高级编程. 北京:人民邮电出版社,20024电脑编程技巧与维护杂志社,Visual C/C+编程精选集锦(数据库和图形图像分册).北京:科学出版社,20035黄承安. Visual C+.NET 经典开发案例. 北京:中国铁道出版社,20036 计算机世界网. 屏幕抓图程序DIY. 2001

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 建筑/施工/环境 > 项目建议


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号