(1.2.梧州学院计算机与电子信息工程系,广西梧州543002)
1 前言
笔者所介绍的屏幕监控是整个局域网多媒体教学系统的一个子功能,负责把学生端的屏幕图像传输
到教师机并进行实时显示,主要用到屏幕拷贝与图像传输技术。笔者以JAVA作为开发平台,使用Robot类
进行屏幕图像的抓取,利用BufferedImage类完成图像的缓冲,基于Socket方式建立局域网内的连接,将
屏幕图像传输到另外一台机器,再进行图像的显示。重点介绍屏幕拷贝技术与图像传输的实现方法和步
骤。
2 屏幕图像获取
要实现对学生机的屏幕监控功能,首先要获取学生机的屏幕图像,对获取的图像进行比例变换,然
后传输到教师机,并在教师机进行显示。屏幕监控功能的实现步骤如图1所示。
java.awt包中的Robot类提供了createScreenCapture(Rectangle screenRect)方法,该方法能创
建一个以屏幕像素为内容的图像,且该图像不包含鼠标指针。该方法返回BufferedImage类的对象,
BufferedImage类定义在java.awt.image包中,继承了java.awt.Image类,但两者有明显的区别,前者
为缓冲区图像,是指直接在计算机内存(缓冲区)中创建的图像,n 后者对应的图像一般是文件。其中,
方法的形式参数为java.awt包中Rectangle类的对象,表示一个矩形,该矩形建立在屏幕坐标系上,坐
标原点在屏幕的左上角,如图2所示,(0,0)为屏幕坐标系的原点。水平向右的方向为x轴正向,垂直向
下的方向表示Y轴正向。其中x,Y表示矩形左上角的顶点在屏幕坐标系中的位置;width,height用以
表示矩形的长度和宽度,单位是像素。x,Y,width,height皆为整型值,定义为JAVA中的int类型。
抓取屏幕图像的操作如下:
Robot robot=new Robot 0:
Rectangle screenRect=new Rectangle(X,Y,width,height);
BufferedImage buffer=robot.createScreenCapture(screenRect):
buffer对象所表示的图像内容,是从(X,y)点算起的长为width个像素宽为height个像素的矩形的
内容。
对于局域网多媒体教学系统而言,教师机监控的是学生机的全屏图像, 因此对学生机的屏幕抓图操
作是全屏拷贝:
Toolkit too1=getToo1kit 0;
Dimension dim=too1.getScreenSize 0://获取屏幕大小
Rectangle screenRect=new Rectangle(0,0,dim.width,dim.height)://矩形为屏幕大小
经过这些操作后,buffer对象所表示的图像内容即为学生机的屏幕图像,图像大小与学生机实际的
分辨率有关。
3 图像转换
在教师机上需要同时显示多台学生机的屏幕图像,因此需要对抓取得到的屏幕图像大小进行转换,
即对上述代码中buffer对象所表示的缓冲区图像进行缩小的转换。图像转换的过程如图3所示。
“转换处理”定义图像处理相关的操作,旋转变换、比例变换、平移变换等。对于BufferedImage,
因为涉及图像缓冲技术, 图像保存在内存中,因此可以对其进行像素级的处理,完成极其复杂的图像变
换加工。原始的做法为编写针对像素RGB值或显示位置进行操作的具体代码。图像比例变换的变换矩阵
如图4所示。
图4中,x木,y水表示转换后的像素坐标,X,Y表示转换前的像素坐标。SX表示x方向的缩放系数,
sy表示y方向的缩放系数。为了避免上述复杂的操作,JAVA提供了可直接操作的方法来处理类似问题。
java.awt.geom包中的AffineTransform类结合java.awt.image包中的AffineTransform0p类可实现比
例变换:
AffineTransform atm=new AffineTransform 0:
atm.setToScale(SX,sy)://x,Y方向的缩放系数
AffineTransform0p ap=new AffineTransformOp(atm,nul1):
ap.fi I ter(buffer,target)://通过输入buffer得到输出target
4 传输图像
数据在网络中进行通信,有两种方式:面向连接形式和数据报形式。但图像的传输与数据的传输
有着明显区别,数据传输对延时等问题没有过高的要求。 ,图像的传输对实时性和同步性要求较高。参
考文献[3]提出采用数据报的形式进行图像的实时传输,尽管在一定程度上强调了传输速度,但对数据完
整性要求不高,会引起经常性的图像显示不完整。笔者选择的是基于Socket的面向连接方式,它提供点
对点的可靠连接,并且通过使用ImageIO类的方法直接读写图像,比起用字节数组的方式去读写图像来说
速度要快很多。ImageIO类定义在javax.imageio包中,可以读写数据流中的图像信息,并且能够进行简
单的编码与解码。JAVA中的Socket通信主要由两方面组成:Socket类和ServerSocket类,在java.ne t包
中定义。
笔者设计学生机作C1ient端,教师机作Server端。对于屏幕监控,是把学生机的屏幕图像实时地
动态地传输并显示到教师机上。学生机为数据的发送端,教师机为数据的接收端。
学生端主要代码:
Socket st=new Socket( 192.168.0.100 ,8888)://192.168.0.100为教师机IP
out=st.getOutputStream 0://创建输出流对象out,定义为OutputStream类型
ImageIO.write(target, bmp ,out);//按bmp格式输出缩小后的屏幕图像target
在接收端通过调用构造方法ServerSocket (int port,int backlog)创建ServerSocket类的对象,
指定针对某个具体端口号的Socket通信,且最多允许backlog个连接请求,再通过该对象调用accept 0
方法等待并接受发送端的连接请求。在发送端通过调用构造方法Socket(InetAddress address,int port)
创建Socket类的对象,建立与接收端的连接。
教师端主要代码:
ServerSocket sst=new ServerSocket(8888,loo):
Socket socket=sst.accept 0:
in=socket.getInputStream 0;//~,J建输入流对象in,定义为InputStream类型
bi=ImagelO.read(in)://读取学生端传来的屏幕图像,bi为BufferedImage类型
5 显示图像
学生机的屏幕图像传输到教师机后,读出的图像为BufferedImage类型。接下来的关键操作就是显
示该图像。
java.awt包中的Graphics2D类通过继承Graphics类,得到drawlmage(Image img,int X,int Y,
ImageObserver observer)方法,可绘制缓冲区中的图像。重写paint方法:
publ ic void paint(Graphics g)
{
Graphics2D t=(Graphics2D)g:
t.drawlmage(bi,0,0,thi s):
)
(本文来自 教程天下:www.nba114.com)