屏幕广播开发.docx

上传人:b****0 文档编号:12584242 上传时间:2023-04-20 格式:DOCX 页数:38 大小:202.32KB
下载 相关 举报
屏幕广播开发.docx_第1页
第1页 / 共38页
屏幕广播开发.docx_第2页
第2页 / 共38页
屏幕广播开发.docx_第3页
第3页 / 共38页
屏幕广播开发.docx_第4页
第4页 / 共38页
屏幕广播开发.docx_第5页
第5页 / 共38页
点击查看更多>>
下载资源
资源描述

屏幕广播开发.docx

《屏幕广播开发.docx》由会员分享,可在线阅读,更多相关《屏幕广播开发.docx(38页珍藏版)》请在冰豆网上搜索。

屏幕广播开发.docx

屏幕广播开发

屏幕广播开发

摘要

软件项目内容概述

该软件是应用在windows系列操作环境下的,它由两个程序组成,教师机程序和学生机程序。

教师机程序获取教师机屏幕位图,将位图数据压缩后,通过网络在特定的组播地址和端口上将屏幕位图数据发送出去。

学生机程序从网络上接收教师机屏幕位图数据,解压后显示在学生机的整个屏幕上,学生机屏幕同教师机屏幕图象保持同步,实现软件分屏显示,替代传统的硬件分屏方式。

该软件非常适用远程计算机教学系统,譬路,在北京的教师演示操作某个计算机软件的使用时,所有外地的学生机屏幕上都显示教师机屏幕上的内容,即将远端教师的计算机屏幕呈现在每个学生面前。

教师与学生的计算机是通过卫星,光缆,Cable等能够实现远距离传输的网络连接在一块的。

从网络的分层协议上来看,本软件属于采用TCP/IP协议的应用层软件,与底层的网络实现方式无关,只要网络支持TCP/IP协议即可。

所以本软件也可用于本地局域网,事实上,本软件的开发调试就是在局域网环境下进行的,然后在应用到远程网络上的。

实现原理:

该软件由两个程序组成,教师机程序和学生机程序。

教师机程序首先获得教师屏幕窗口句柄,屏幕实质上也是一个特殊的窗口,这样便可获得屏幕窗口所对应的位图图象,将这个位图图象的数据通过网络在设定的组播地址和端口上发送出去。

学生机程序在设定的组播地址和端口上接收网络数据,一但接收到老师机屏幕位图图象的完整数据后,便可根据这些数据在学生机内存中生成教师机屏幕图象。

然后,学生机产一个与屏幕同样大小的无边框窗口,显示在桌面的最顶层,并将在内存中生成教师机屏幕图象粘贴到这个新生成的窗口上,这样,学生机的整个桌面上将显示为教师机的屏幕图象。

教师机程序在上一幅屏幕图象成功传输后,再次获取当前时刻的屏幕图象。

当前屏幕图象根据计算机的运行情况,与上一幅图象相比,只是局部发生改变,或是完全相同。

为了降低网络数据传输量,节省网络带宽,在传输当前屏幕图象时,教师机程序将比较当前屏幕图象与上一幅图象数据的内容,获得变化过的图象区域,然后通过网络将当前屏幕图象上变化过的图象区域位置及图象数据传送给学生机。

学生机程序从网络上接收到教师机当前屏幕图象上变化过的图象区域位置及图象数据后,根据区域位置用该区域的图象数据更新上幅图象的对应区域数据,使学生的屏幕与老师的屏幕保持一致,从而实现软件分屏显示的功能。

由于屏幕图象的变化区域形状并不规则,甚至是若干小的不相邻区域,很难找到合适的数据模型来描述。

为了简化程序开发难度,将整个屏幕图象用32*32象素区域块进行分割

这个当前屏幕图象与上一幅图象进行比较时,实际上是逐个按32*32象素区域进行比较,只要象素区域中有一点不同,就说明`这个32*32象素区域有变化,另外,为了更有效的降低网络数据的传送量,节省网络带宽,将每一块32*32象素数据进行压缩,压缩后在网络上发送出去。

学生机程序接受到每一个网络数据,并对其进行解压缩,恢复该区域的数据,

技术要点:

屏幕图象的处理过程

一.位图图象格式

由于我们所获得的屏幕图象是位图格式,所以首先必须了解位图格式。

BMP文件的结构

文件头

位图信息头

色彩表

位图阵列

(位图文件结构)

1.文件头

文件头含有位图文件的类型,大小,数据结构等信息,文件头由下面一个结构组成:

typedefstructtagBITMAPFILEHEADER{//BMFH

WORDbfTupe;

DWORDbfSize;

WORDbfReserved1;

WORDbfReserved2;

DWORDbfOffBits;

}BITMAPFILEHEADER;

在上面结构中,每一个成员的含义解释是如下:

bfType表明位图文件的类型,必须为BM;

bfSize表明位图文件的大小,以字节为单位;

bfReserved1代表保留字,必须为0;

bfReserved2也是保留字,必须为0;

bfOffBits表明位图阵列的起始位置,也就是位图阵列相对于位图文件头的偏移量,以字节为单位;

由于本软件中没有对位图文件的操作,在获取屏幕位图,显示位图都是在内存中直接进行的,只需要位图信息头,色彩表,位图阵列数据等就可以了。

因此,程序中没有用到位图文件头这个结构。

2.位图信息头

位图信息头含有DIB(device-independentbitmap)与设备无关位图的大小和颜色格式。

信息头由下面一个结构组成:

tyopedefstructtagBITMAPINFOHEADER{

DWORDbiSize;

LONGbiHeight;

WORDbiplanes;

WORDbiBitCount;

DWORDbiCompression;

DWORDbiSizeImage;

LONGbiXPelsPerMeter;

LONGbiYPelsPerMeter;

DWORDbiClrUsed;

DWORDbiClrImportant;

}BITMAPINFOGEADER;

以上每个字段的具体含义解释如下;

biSize代表BITMAPINFOGEADER结构所需要的字节数。

biWidth,biHeigh代表一象素为单位的BMP图象的宽度和高度。

BiPlatles给出输出设备的平面数,必须置为1。

biBitCount给出每个象数的位数。

biCompress表示该图象所用的压缩类型。

biSizeImage代表图象字节数

biXPelsPerMeter代表图象的水平分辨率(以目标设备的每米象素数为单位)。

biYPelsPerMeter代表图象的垂直分辨率(以目标设备的每米象素数为单位)。

BiClrUsed给出调色板中图象实际使用的颜色数。

若此值为0,那么图象使用的颜色由biBitCount的值确定;若此值不为0,当bitBitCount的值小于16,则biClrUsed给出图形设备驱动程序或设备驱动程序将访问的实际使用的颜色数。

当bitBitCount大于等于16,则biCirUsed给出用于优化调色板性能的参考色彩表的大小。

BiClrImportant给出对于图象显示来说是重要的颜色索引值。

此值若为0,则所有颜色都是重要的。

3.色彩表

色彩表定义了一个颜色表,用于说明图象中的颜色。

它有若干个表项,每一个表项都由RGBQUAD结构定义了一种颜色,每一种颜色都可由红、绿、蓝三个基色的不同分量组合而成,RGBQUAD实际上描述了一种颜色的红、绿、蓝三色的分量。

RGBQUAD结构定义如下:

typedefstructtagRGBQUAD{//rgbq

BYTErgbBlue;

BYTErgbGreen;

BYTErgbRed;

BYTErgbReserved;

}RGBQUAD;

色彩表中表项的个数由biBitCount来定:

当biBitCount=1、4、8时,色彩表分别有2,16,256个表项;若某点的象素值为n,则该象素的颜色为色彩表中的第n项所定义的颜色。

当biBitCount=24时,色彩表表项为空;位图阵列的每3个字节表示一个象素,这3个字节直接定义了象素颜色中的蓝、绿、红的相对亮度。

在RGBQUAD定义的颜色中,兰色的亮度由rgbBlue定义,绿色亮度由rgbGreen定义,红色的亮度由rgbRed定义,rgbReserved必须为零。

若某表项的值为:

FF,00,00,那么他定义的颜色为纯蓝色。

当biBitCount=16,32时,情况较为复杂,并不常用。

4.位图阵列

位图阵列存放图象的所有象素值。

当biBitCount=1、4、8时,位图阵列中每个象素的值是该象素颜色在色彩表中的索引序号。

象素值与色彩表是紧密相关的,对于同样的一个位图图象,如果色彩表不一样,那位图阵列里的象素值也将不一样。

下图是包含有4种颜色,16*4象素的色彩表与位图数据阵列的信息:

色彩表

颜色索引号

红色分量

绿色分量

蓝色分量

0

255

255

0

1

128

255

255

2

0

255

128

3

255

128

128

位图数据阵列

0

1

2

2

2

1

1

1

2

3

3

3

3

3

3

3

2

2

2

2

0

0

0

0

0

0

0

0

0

0

2

2

1

1

1

1

1

1

1

0

0

0

0

0

0

0

2

2

2

2

2

2

3

3

3

3

3

3

1

1

1

1

0

0

其中,位图阵列中的每个象素占用2个bits,其数据是象素颜色对应在色彩表中的索引号。

图象列阵的产生方法是:

从图象的左下脚开始逐行扫描图象,从左到右,从下到上,把图象的象素值全部记录下来。

位图列阵数据的存储格式有压缩和非压缩两种。

由于我们用到的是非压缩格式,所以在此不介绍有压缩格式。

在非压缩格式中,位图中每一个点的象素值对应于位图阵列的若干位,而位图阵列的大小由图象的宽度、高度及图象的颜色数(biBitCount)决定。

4.1图扫描行与位图阵列的关系

一个扫描行的象素值需要满足一定的要求,这种要求是每行的字节数必须为4的倍数,不足的补零。

若记录一个扫描行的象素值需要n个字节,那么公式为:

当(biWidth*biBitCount)能被32整除时;

n=(biWidth*biBItCount)/8。

当(biWidth*biBitCount)不能被32整除时;

n=((biWidth*biBitCount)/32)*4+4。

比实际图象多出的象素其值要用0表示。

位图阵列的大小为n*biHeight字节,位图阵列中第0—n-1个字节代表图象的第一个扫描的象素值,第n—2n-1个字节代表图象的第二个行的象素值,…….,第(I-1)*n---I*n-1个字节代表图象的第I个扫描行的象素值。

4.2位图象素值与位图阵列的对应关系

以第I个扫描行为例,若第I扫描行的象素值的n个字节分别为:

b0,b1….b(n-1),则根据表示一个象素值所需位数的不同,对应关系如下:

当biBtCount=1时,一个象素值可用1比特(1位)表示。

b0的第七位表示位图的第I扫描行的第1个象素值,第6位表示第2个象素值,….,第0位表示第8个象素值;b1第7位表示第I扫描行的第9个象素值,第6位表示第10个象素值,第5位表示第11个象素值,….。

当biBtCount=4时,一个象素值可用4比特(4位)表示。

b0的第7--4位表示位图的第I扫描行的第1个象素值,第3--0位表示第2个象素值,b1第7--4位表示第I扫描行的第3个象素值,第3--0位表示第4个象素值,….。

当biBtCount=8时,一个象素值可用8比特(8位)表示。

b1表示位图的第I扫描行的第1个象素值,b2表示第I扫描行的第2个象素值,……。

当biBtCount=24时,一个象素值可用24比特(24位)表示。

b0,b1,b2表示位图的第I扫描行的第1个象素值,b3,b4,b5表示第I扫描行的第2个象素值,……。

二.获取教师机的屏幕图象

要实现软件屏幕共享功能,首先必须获取教师机的屏幕图象。

对于Windows的每一个窗口都可以看作是屏幕上的一个图象,该图象可以通过程序获得。

Windows的整个桌面也是一个窗口,因此,我们可以获得对应整个桌面的图象。

1.获取教师机屏幕位图句柄

利用CreateCompatibleDC、CreateCompatibleBitmap及BitBlt等API函数能够比较容易地抓取整个屏幕图像,但所抓取屏幕图像不包含当前光标区域。

因此,我们必须先获取窗口屏幕图象,然后获取当前的光标,并将光标画在先前获取的屏幕图象上,生成带光标的新的图象。

获取屏幕图象及光标的程序代码如下:

//获取全屏幕窗口的设备描述表

HDChdcScreen=:

:

GetDC(NULL);

//产生全屏幕窗口设备描述表的兼容设备描述表

m_hdcCompatible=CreateCompatibleDC(hdcScreen);

//产生全屏幕窗口设备描述表的兼容位图

HBITMAPm_hbmScreen=CreateCompatibleBitmap(hdcScreen,

GetDeviceCaps(hdcScreen,HORZRES),GetDeviceCaps(hdcScreen,VERTRES));

//将兼容位图选入兼容设备描述表

SelectObject(m_hdcCompatible,m_hbmScreen);

//将全屏幕窗口位图的象素数据拷贝到兼容设备描述表

BitBlt(m_hdcCompatible,0,0,GetDeviceCaps(hdcScreen,HORZRES),

GetDeviceCaps(hdcScreen,VERTRES),hdcScreen,0,0,SRCCOPY);

//获取当前光标及其位置

HCURSORhCursor=GetCursor();

POINTptCursor;

GetCursorPos(&ptCursor);

//获取光标的图标数据

ICONINFOIconInfo;

if(GetIconInfo(hCursor,&IconInfo))

{

ptCursor.x-=((int)IconInfo.xHotspot);

ptCursor.y-=((int)IconInfo.yHotspot);

if(IconInfo.hbmMask!

=NULL)

DeleteObject(IconInfo.hbmMask);

if(IconInfo.hbmColor!

=NULL)

DeleteObject(IconInfo.hbmColor);

}

//在兼容设备描述表上画出该光标

DrawIconEx(

m_hdcCompatible,//handletodevicecontext

ptCursor.x,ptCursor.y,

hCursor,//handletoicontodraw

0,0,//widthoftheicon

0,//indexofframeinanimatedcursor

NULL,//handletobackgroundbrush

DI_NORMAL|DI_COMPAT//icon-drawingflags

);

在上面的程序代码中,有几点需要特别注意:

1).每个设备描述表中都包含有一个位图,CreateCompatibleDC返回的兼容设备描述表所包含的位图大小仅为一个象素,并且是单色图像。

2).CreateCompatibleBitmap返回的位图对象只包含相应设备表述表中的位图的位图信息头,不包含颜色表和象素数据块。

因此,选入该位图对象的设备描述表不能象选入普通位图对象的设备描述表一样应用,必须在SelectObject函数之后,调用BitBlt将原始设备描述表的颜色表及象素数据块拷贝到兼容设备描述表。

3).获取光标图像的程序代码中,GetCursorPos所取回的坐标点是光标的中间点的位置,而DrawIconEx函数所要求的坐标值为光标的左上角坐标,因此,要调用GetIconInfo对坐标点进行转换。

2.获取屏幕图象位图的位图信息及位图象素数据阵列

在上面程序代码中,我们已经获得了教师机屏幕位图图象的句柄,位图句柄本身并不包含位图信息头和位图象素数据阵列。

要在学生机上显示教师屏幕位图图象,必须将位图信息头和位图象素数据阵列传送到学生机。

调用GetDIBits函数可以获得位图句柄所对应的位图的信息头和位图象素数据阵列,GetDIBits函数的定义如下:

intGetDIBits(

HDChdc,//设备描述表的句柄

HBITMAPhbmp,//位图句柄

UINTuStartScan,//从位图检索数据的起始行

UINTcScanLines,//准备检索的总行数

LPVOIDlpvBits,//用于检索位图阵列数据的内存块

LPBITMAPINFOlpbi,//用于检索位图信息头的内存块

UINTuUsage//色彩表中的数据格式

);

如果lpvBits等于NULL,该函数检索位图信息填充到lpbi的位图信息头部分。

要检索出lpvBits的数据和lpbi中的色彩表,必须真确设置lpbi的位图信息头内容,所以,要获得位图的信息头和位图象素数据阵列,必须调用两次GetDIBits,第一次让lpvBits等于NULL,以获得lpbi的位图信息头,第二次调用让lpvBits指向准备接收位图象素数据阵列的内存块,并将传入刚才获得的lpbi。

程序代码如下:

PBITMAPINFOm_pbmi;//在类中定义的成员变量,以在其他函数中也能应用

m_pbmi=(PBITMAPINFO)LocalAlloc(LPTR,sizeof(BITMAPINFOHEADER)+

256*sizeof(RGBQUAD));

m_pbmi->bmiHeader.biSize=sizeof(BITMAPINFOHEADER);

m_pbmi->bmiHeader.biBitCount=0;

if(!

GetDIBits(m_hdcCompatible,m_hbmScreen,0,1,NULL,m_pbmi,DIB_RGB_COLORS))

{

AfxMessageBox("GetDibitsforBitampInfoerror!

",MB_OK,NULL);

Return;

}

LPBYTElpBits;

lpBits=(LPBYTE)GlobalAlloc(GMEM_FIXED,m_pbmi->bmiHeader.biSizeImage);

if(!

lpBits)

{

AfxMessageBox("Allocmemoryerror",NULL,NULL);

Return;

}

//Retrievethecolortable(RGBQUADarray)andthebits

//(arrayofpaletteindices)fromtheDIB.

if(!

GetDIBits(m_hdcCompatible,m_hbmScreen,0,(WORD)(m_pbmi->bmiHeader.biHeigh,

lpBits,m_pbmi,DIB_RGB_COLORS))

{

AfxMessageBox("GetDibitsforBitampInfoerror!

",NULL,NULL);

Return;

}

三.在学生机屏幕上显示教师屏幕图象

1.根据从网络上接收到的教师机屏幕位图图象的色彩表创建一个逻辑调色板。

2.创建一个屏幕大小的无边框窗口。

3.将逻辑调色板选入该窗口设备描述表。

4.调用StrechDIBits在学生机屏幕上输出教师机屏幕图象。

任何一种颜色都可由红(R)、绿(G)、蓝(B)三个基色组合而成,用R,G,B颜色分量来表示数字图象象素的颜色值的方法就是RGB法。

如用于表示R,G,B颜色分量的位数分为n1,n2,n3,则可表示的象素的颜色数为2(n1+n2+n3)。

如果分别用8位来表示三颜色分量,则总共需要24位来表示RGB三色,可表示的颜色数为2(24)=16,777,216。

一个调色板是一个数组,其中包含当前输出设备(显卡、打印机)能够显示和画出的颜色的所对应的数字,该数字由红、绿、蓝三个基色的分量值组成。

调色板主要用于输出设备能够产生许多颜色,但输出设备实际上在任何时候都只能输出其中的部分颜色,例如,输出设备能够产生512种颜色,但在任何时候都只能输出其中的256种颜色,这256种颜色可以是这512种颜色中的任意组合。

对于这样的设备,系统维护一个用于跟踪和管理当前输出设备的颜色的系统调色板。

应用程序不能直接访问系统调色板,而是由系统为每个设备描述表安排一个缺省的调色板,对于刚才的例子,这个调色板就包含了512种颜色中的256种颜色,应用程序可以使用这个缺省的调色板。

应用程序也可以根据需要产生一个逻辑调色板,并把它安排到某个特定的设备描述表。

对于刚才的例子,当要显示一个256色的位图图象时,位图图象的某些颜色不在确省的调色板中,我们就要产生一个逻辑调色板,让其包含位图图象中的256种颜色,并把这个逻辑调色板安排到准备输出这个位图图象的设备描述表上。

CClientDCdc(m_pWnd);//m_pWnd是用于显示教师机屏幕位图的窗口

CPalettelPalDIB;

LPLOGPALETTElpPal;

HPALETTEhOldPal;

if(m_pbmi->bmiHeader.biBitCount<16)

{lpPal=(LPLOGPALETTE)GlobalAlloc(GMEM_FIXED,sizeof(LOGPALETTE)+

sizeof(PALETTEENTRY)*(1<bmiHeader.biBitCount));

lpPal->palVersion=0x300;

lpPal->palNumEntries=1<bmiHeader.biBitCount;

for(inti=0;ipalNumEntries;i++)

{

lpPal->palPalEntry[i].peRed=m_pbmi->bmiColors[i].rgbRed;

lpPal->palPalEntry[i].peGreen=m_pbmi->bmiColors[i].rgbGreen;

lpPal->palPalEntry[i].peBlue=m_pbmi->bmiColors[i].rgbBlue;

lpPal->palPalEntry[i].peFlags=0;

}

lPalDIB.CreatePalette(lpPal);

hOldPal=SelectPalette(dc.m_hDC,(HPALETTE)(lPalDIB.m_hObject),TRUE);

RealizePalette(dc.m_hDC);

GlobalFree(lpPal);

}

SetStretchBltMode(dc.m_hDC,COLORONCOLOR);StretchDIBits(dc.m_hDC,0,0,GetSystemMetrics(SM_CXSCREEN),

GetSystemMetrics(SM_CYSCREEN

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

当前位置:首页 > PPT模板 > 图表模板

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1