Java Robot对象实现服务器屏幕远程监视
有时候,在Java应用程序开发中,如:远程监控或远程教学,常常需要对计算机的屏幕进行截取,由于屏幕截取是比较接近操作系统的操作,在Windows操作系统下,该操作几乎成了VC、VB等的专利,事实上,使用Java JDK1.4 的Robot对象,来完成"屏幕截取操作,更加简单。Java JDK1.4 的Robot对象,该对象可以完成对"屏幕"像素的拷贝,完成屏幕图像截取操作。Java应用程序中可以直接调用此对象,完成对特定应用程序的屏幕截取,如果将此功能配合网络,便可以轻而易举地实现远程服务器屏幕的监视。本文向大家介绍如何用Java构建屏幕"照相机"并实现远程服务器屏幕的监视,并给出了相应的Java源代码。
关键词:
Java, Robot, 屏幕截取
1 引言
在Java应用软件演示或相关教学培训,或远程监控过程中,我们常常要截取软件运行GUI界面,并将其保存到一个或一系列图像文件中。目前,在Windows平台下,有关屏幕截取的工具软件有许多,比如:HyperCam等,当然还可以直接利用Windows操作系统支持的屏幕拷贝Print Screen键,将屏幕拷贝到剪贴板,在保存为图像文件。这些工具软件一定要屏幕截取者,在操作过程中要"精力集中"并且"伺机捕获"所需要的软件运行界面。事实上,有时候我们需要Java应用程序,自动对运行的GUI界面进行"拍照",比如:一台计算机要获取网络上另一台计算机(可能是网络服务器)正在运行的GUI界面,要看看对方计算机上软件运行情况。这就需要在Java应用程序中,自动将运行的GUI界面保存到一个图像文件中,然后通过网络传输到另一台计算机上。而上述HyperCam等工具软件无法与我们的Java应用融合为一体。因此,我们需要在Java应用程序中编写一个屏幕"照相机"。
2 Java屏幕"照相机"的编写原理
"屏幕的截取"是比较接近操作系统底层的操作,在Windows平台下,该操作似乎成了VC、VB等语言开发的专利。事实上,"屏幕的截取"在Java应用程序中,及其简单,核心代码只需要几行。在Java JDK1.4 中提供了一个"机器人"Robot类。该类用于产生与本地操作系统有关的底层输入、测试应用程序运行或自动控制应用程序运行。Robot类提供了一个方法:.createScreenCapture(..),可以直接将全屏幕或某个屏幕区域的像素拷贝到一个BufferedImage对象中,我们只需要将该对象写入到一个图像文件之中,就完成了屏幕到图像的拷贝过程。
3 Java屏幕"照相机"的实现
为了构造一个比较完善的Java屏幕"照相机",我们构造了一个GuiCamera JavaBean,其源代码和说明如下:
package Camera;
import java.awt.p_w_picpath.BufferedImage;
import java.io.*;
import javax.p_w_picpathio.*;
import java.awt.*;
/*******************************************************************
* 该JavaBean可以直接在其他Java应用程序中调用,实现屏幕的"拍照"
* This JavaBean is used to snapshot the GUI in a
* Java application! You can embeded
* it in to your java application source code, and us
* it to snapshot the right GUI of the application
* @see javax.ImageIO
* @author liluqun ([email]liluqun@263.net[/email])
* @version 1.0
*
*****************************************************/
public class GuiCamera {
private String fileName; //文件的前缀
private String defaultName = "GuiCamera";
static int serialNum=0;
private String p_w_picpathFormat; //图像文件的格式
private String defaultImageFormat="png";
Dimension d=Toolkit.getDefaultToolkit().getScreenSize();
/****************************************************************
* 默认的文件前缀为GuiCamera,文件格式为PNG格式
* The default construct will use the default
* Image file surname "GuiCamera",
* and default p_w_picpath format "png"
****************************************************************/
public GuiCamera() {
fileName = defaultName;
p_w_picpathFormat=defaultImageFormat;
}
/****************************************************************
* @param s the surname of the snapshot file
* @param format the format of the p_w_picpath file,
* it can be "jpg" or "png"
* 本构造支持JPG和PNG文件的存储
****************************************************************/
public GuiCamera(String s,String format) {
fileName = s;
p_w_picpathFormat=format;
}
/****************************************************************
* 对屏幕进行拍照
* snapShot the Gui once
****************************************************************/
public void snapShot() {
try {
//拷贝屏幕到一个BufferedImage对象screenshot
BufferedImage screenshot = (new Robot()).createScreenCapture(new
Rectangle(0, 0, (int) d.getWidth(), (int) d.getHeight()));
serialNum++;
//根据文件前缀变量和文件格式变量,自动生成文件名
String name=fileName+String.valueOf(serialNum)+"."+p_w_picpathFormat;
File f = new File(name);
System.out.print("Save File "+name);
//将screenshot对象写入图像文件
ImageIO.write(screenshot, p_w_picpathFormat, f);
System.out.print("..Finished!\n");
}
catch (Exception ex) {
System.out.println(ex);
}
}
}
4 Java屏幕"照相机"的应用
直接使用上述GuiCamera JavaBean,构造一个对象,在需要截取屏幕的地方,调用一下这个对象的.snapShot()方法即可对屏幕进行自动"拍照"!由于对屏幕的截取是程序自动进行的,我们无需象使用HyperCam工具软件那样,在手工操作过程中要"精力集中"并且"伺机捕获"所需要的软件运行界面了。
如:GuiCamera cam= new GuiCamera("d:\\Hello", "png");
cam.snapShot();
就可以的到文件名为:Hello**.png等一系列所截取的屏幕图像文件。
上述代码旨在"抛砖引玉",Java应用程序开发人员,可以在此基础上,如果将此GuiCamera JavaBean与增加多线程和网络功能,可以实现远程监控网络上另一台计算机屏幕。
5 远程服务屏幕的监视
在上述代码的基础上,我们稍加改造,封装成一个Servlet,便可以实现浏览器/服务器(B/S)计算结构 模式的小应用。客户端浏览器访问服务器上的Servlet时候,服务器拷贝服务器屏幕,并按照contentType="Image/Jpeg"文件相应格式,将拷贝的数据按照二进制数据流的方式返回客户端,客户端使用浏览器便可以查看远程服务器的屏幕,从而实现服务器屏幕的远程监视。
主要代码如下:
package li;
import javax.p_w_picpathio.ImageIO;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.p_w_picpath.BufferedImage;
import java.awt.Dimension;
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
import java.util.*;
public class SnapShot
extends HttpServlet
implements SingleThreadModel {
private static final String CONTENT_TYPE = "p_w_picpath/jpeg";
//Initialize global variables
public void init() throws ServletException {
}
//Process the HTTP Get request
public void doGet(HttpServletRequest request, HttpServletResponse
response) throws ServletException, IOException {
//设置客户端的文件相应类型
response.setContentType(CONTENT_TYPE);
//获取屏幕的分辨率
Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
try {
{BufferedImage screenshot = (new Robot()).createScreenCapture(new
Rectangle(0, 0, (int) d.getWidth(), (int) d.getHeight()));
String p_w_picpathFormat = "jpg";
ServletOutputStream sos = response.getOutputStream();
//将图像数据流写入客户端
ImageIO.write(screenshot, p_w_picpathFormat, sos);
sos.close();
response.flushBuffer();
}
}
catch (Exception ex) {
}
}
//Clean up resources
public void destroy() {
}
}
运行结果如下:(以上代码在Jbuilder10,JDevelop9 下调试成功!)
上述代码只实现了远程服务器屏幕的监视,如果要实现服务器"控制"也非常简单,只要浏览器客户向服务器发送请求,服务器返回可客户一包含服务器屏幕的表单,可以通过表单将客户鼠标点击服务器屏幕图像的位置发送给服务器,服务器端使用Robot对象控制鼠标对象的位置与动作便可实现服务器的远程"控制"。
JAVA捕获屏幕、屏幕录像、播放
//记录屏幕、类似录像
package net.wnetw.project.media;
import java.awt.*;
import java.awt.p_w_picpath.*;
import com.sun.p_w_picpath.codec.jpeg.*;
import java.io.*;
/**
* @author 网全社区
*/
public class WnetWScreenRecorder extends Thread{
private Dimension screenSize;
private Rectangle rectangle;
private Robot robot;
private long i = 0;
private JPEGImageEncoder encoder;
public WnetWScreenRecord() {
screenSize = Toolkit.getDefaultToolkit().getScreenSize();
rectangle = new Rectangle(screenSize);//可以指定捕获屏幕区域
try{
robot = new Robot();
}catch(Exception e){
e.printStackTrace();
System.out.println(e);
}
}
public static void main(String[] args) {
new WnetWScreenRecord().start();
}
public void run(){
FileOutputStream fos = null;
while (true){
try{
BufferedImage p_w_picpath = robot.createScreenCapture(rectangle);//捕获制定屏幕矩形区域
fos = new FileOutputStream("C:\\records\\" + i + ".jpg");
JPEGCodec.createJPEGEncoder(fos).encode(p_w_picpath);//图像编码成JPEG
fos.close();
i = i + 1;
Thread.sleep(40);//每秒25帧
}catch(Exception e){
e.printStackTrace();
System.out.println(e);
try{
if (fos != null)fos.close();
}catch(Exception e1){}
}
}
}
}
//播放屏幕录像
package net.wnetw.project.media;
import java.awt.*;
import javax.swing.*;
import java.io.*;
/**
* @author 网全社区
*/
public class WnetWScreenRecordPlayer extends JFrame{
BorderLayout borderLayout1 = new BorderLayout();
Dimension screenSize;
public WnetWScreenRecordPlayer() {
super();
screenSize = Toolkit.getDefaultToolkit().getScreenSize();
this.setSize(screenSize);
Screen p = new Screen();
Container c = this.getContentPane();
c.setLayout(borderLayout1);
c.add(p,"Center");
new Thread(p).start();
this.show();
}
public static void main(String[] args){
new WnetWScreenRecordPlayer();
}
}
class Screen extends JPanel implements Runnable{
private BorderLayout borderLayout1 = new BorderLayout();
private Image cp_w_picpath;
public void run(){
int i = 0;
while(true){
try{
cp_w_picpath = loadImage(i + ".jpg");
i = i + 1;
repaint();
Thread.sleep(40);//与录像时每秒帧数一致
}catch(Exception e){
e.printStackTrace();
System.out.println(e);
}
}
}
public Image loadImage(String name) {
Toolkit tk = Toolkit.getDefaultToolkit();
Image p_w_picpath = null;
p_w_picpath = tk.getImage("C:/records/" + name);
MediaTracker mt = new MediaTracker(this);
mt.addImage(p_w_picpath, 0);
try {
mt.waitForID(0);
}catch (Exception e) {
e.printStackTrace();
System.out.println(e);
}
return p_w_picpath;
}
public Screen() {
super();
this.setLayout(null);
}
public void paint(Graphics g){
super.paint(g);
Graphics2D g2 = (Graphics2D) g;
g2.drawImage(cp_w_picpath, 0, 0, null);
}
}
[url]http://blog.ccidnet.com/blog-htm-uid-50032.html[/url]
转载于:https://blog.51cto.com/figo886/46520
相关文章:

Oracle常用傻瓜问题1000问
1. Oracle安装完成后的初始口令? internal/oracle sys/change_on_install system/manager scott/tiger sysman/oem_temp 2. ORACLE9IAS WEB CACHE的初始默认用户和密码? administrator/administrator 3. oracle 8.0.5怎么创建数据库? 用orainst。如果有motif界面&…

安装需要的第三方库时,命令行输入pip提示不是内部或外部命令
简介 在做Python开发时,安装需要的第三方库时,大多数人喜欢选择在命令行用pip进行安装。 然而有时敲入pip命令会提示‘pip’不是内部或外部命令。。如图: 解决办法 1、在python安装目录中找得到script文件夹,查看文件夹内部是否存…

ehcache导致Tomcat重启出错
最近使用ehcache出现了问题,只要在配置文件中打开缓存,Tomcat在重启时就会报内存溢出异常。按说ehcache自己开启的资源,应该自己关闭才是。经查阅资料发现,需要在web.xml中配置一个监听器,该监听器会在应用程序关闭的时…

[置顶]完美简版学生信息管理系统(附有源码)管理系统
简版学生信息管理系统 目前为止找到的简版系统中最新、最全的java类管理系统 点击进入简版系统 如果无法直接连接,请进入: https://blog.csdn.net/weixin_43419816/article/details/104234590 做CSDN最完美的搬运工!

怎样成为一名优秀的系统工程师
一个优秀的系统集成工程师(包括售前和实施)的技术线路笔者注:并不是每个都要求掌握,只是寻找自己的一条技术线路1:网络基础知识:深刻理解网络基本概念,例如>ISO/OSI、TCP/IP、VLAN、各种LAN、WAN协议、各种路由协议、NAT等等Cisco…

星期六第一次加班
虽然说老板叫我们加班,但是貌似没有我什么事情的饿,和张明在一起,真的很不自在,我知道我很自大,我在漫漫的改变自己,他听不惯我说话,但是有什么的呢!我相信他是一个好的程序员&#…
WPF入门(三)-几何图形之不规则图形(PathGeometry) (2)
WPF入门(三)->几何图形之不规则图形(PathGeometry) (2) 原文:WPF入门(三)->几何图形之不规则图形(PathGeometry) (2)上一节我们介绍了PathGeometry中LineSegment是点与点之间绘制的一条直线,那么我们这一节来看一下点与点之间绘制曲线ArcSegment 先来看一段代…

zookeeper图形工具——zkui
虽然zookeeper安装包提供了客户端工具zkcli,但是命令特别少 ,每次想看看里面的节点信息特别费劲。 幸好有图形工具——zkui,https://github.com/echoma/zkui,下载地址 https://github.com/echoma/zkui/wiki/Download。 上个图&…

第一篇博客,java学生管理系统(挑战全网最全)
java学生信息管理系统,(课设必备),附有源码和简版链接 博主虽然技术不高,但是系统写的真的是没话说,留着开学java课设用了。 直接转载链接了,查看系统入口 https://blog.csdn.net/weixin_4341…
ccna实验大全
ccna实验大全启动接口,分配IP地址: router> router> enable router# router# configure terminal router(config)# router(config)# interface Type Port router(config-if)# no shutdown router(config-if)# ip address IP-Address Subnet-Mask r…

实现分布式服务注册及简易的netty聊天
现在很多地方都会用到zookeeper, 用到它的地方就是为了实现分布式。用到的场景就是服务注册,比如一个集群服务器,需要知道哪些服务器在线,哪些服务器不在线。 ZK有一个功能,就是创建临时节点,当机器启动应用的时候就会…

《深入理解计算机系统》学习心得二:关于show-bytes的 学习
此段代码,使用强制类型转换来访问和打印不同程序对象的字节表示。show-bytes打印出每个以十六进制表示的字节。 /* show-bytes - prints byte representation of data */ /* $begin show-bytes */ #include <stdio.h> /* $end show-bytes */ #include <st…

Jquery基础:append、prepend、after、before、appendTo的区别
append() 是在被选元素的结束标签前面(即改被选元素的内部)插入指定内容。 <html><head><script type"text/javascript" src"/jquery/jquery.js"></script><script type"text/javascript"> $().ready(…

域名删除时间及whois状态说明
国际域名状态 Active : 正常状态; Registry-hold:注册局暂停,域名没有解析,不能正常使用,可以续费; Registry-lock:注册局锁定,域名有解析,正常使用,不能更改…

JavaScript中的正则表达式解析
正则表达式(regular expression)对象包含一个正则表达式模式(pattern)。它具有用正则表达式模式去匹配或代替一个字符串(string)中特定字符(或字符集合)的属性(properties)和方法(methods)。 要为一个单独的正则表达式添加属性,可以使用正则表达式构造函数(constructor functio…

Markdown上下标内容多于一项
用{ }括起来。转载于:https://www.cnblogs.com/144823836yj/p/10261391.html

详述FileUpload 控件上传单文件
第一步:添加两个Label控件,一个是用于标题显示,一个是用于上传完成消息提示。 第二步:创建一个FileUpload控件到Page页面,注意FileUpload控件本身只提供文件的选举操作,而实际的文件上传功能需要我们创建一…

基于μC/OS—III的CC1120驱动程序设计
基于μC/OS—III的CC1120驱动程序设计 时间:2014-01-21 来源:电子设计工程 作者:张绍游,张贻雄,石江宏关键字:CC1120 嵌入式操作系统 STM32F103ZE 驱动设计 摘要:本文根据实…

LinkQueue的基本创建
队列是一种先进先出(first in first out,缩写为FIFO)的线性表。它只允许在表的一端进行插入,而在另一端进行删除元素。和平常我们排队打饭类似。 链队列是用链表表示的队列的简称。一个链队列需要两个分别指示队头和队尾的指针(分…

请教一个算法问题,有两个数组A,B,判断A中是否至少有一个元素和B中元素相同...
最笨的办法当然是二层嵌套循环,但觉得应该有更好的方法,但是着实想不出来,想听听大家的意见,大家帮帮小弟 i.e string[] A{"X","Y","Z","W"}; string[] B{"X","E",&…

超市账单管理系统之-------登录
报500的错大部分都是springmvc的jar包没有导对,最好用3点几的版本 。。。。在项目中要把包导对 pom.xml 所需要的jar包 1 <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"2 xs…

进制转换converse
栈和队列是在软件设计中常用的两种数据结构,它们的逻辑结构和线性表相同。 其特点在于运算受到了限制:栈按“后进先出”的规则进行操作,队按“先进先出”的规则进行操作,故称运算受限制的线性表。 从数据类型的角度看: 它们和线…

40.多进程同步--锁--多把锁
多进程同步 首先多进程默认是并发行为,多个进程同时执行执行的顺序,以及何时执行完毕无法控制 多个进程如果涉及到了通信,数据的有序性无法保证需要锁来控制进程之间执行的顺序对于进程资源的控制缺点:同步进程,并发没…

.net导出到Excel与Word中(带上下标)
//输出到excel的函数,可直接copy到 cs页面privatevoidOutExcel(GridView dg, stringname) { dg.Visible true; Response.Clear(); Response.Buffer true; Response.Charset "GB2312"; name "attachment;filename&quo…

越来越不想写代码了
越来越不想写代码了今天刚下载了PD12版本,做了一个需求分析以及试用了几个新功能在对C#支持的情况。感觉非常不错,特别是在代码生成方面,比我想的要好多了,而且比起其它语言的代码生成,好像就是对C…

【代码笔记】Web-CSS-CSS id和Class选择器
一,效果图。 二,代码。 <!DOCTYPE html> <html> <head> <meta charset"utf-8"> <title>CSS id和class选择器</title> <style> #para1 { text-align: center; color: red; } .center { text-align: …

javascript取得鼠标的位置
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns"http://www.w3.org/1999/xhtml"><head><title>JavaScript得到鼠标坐标<…

nginx缓存功能的设置
首先用的缓存是proxy_cache. 在http段里加入下列几句: [plain] view plaincopy proxy_connect_timeout 5; proxy_read_timeout 60; proxy_send_timeout 5; proxy_buffer_size 16k; proxy_buffers 4 64k; proxy_busy_buffers_size 128k; proxy_tem…

线性表List的基本创建
#include <iostream> using namespace std; #include <malloc.h> #include <stdio.h> #define TURE 1 #define FALSE 0 #define OK 1 #define ERROR 0 #define IINFEASIBLE -1 #define OVERFLOW -2 typedef int Status; /*类型名定义用status代替int;Sta…

点点看 只有想不到没有看不到
看了这些好看的图片,不禁也想把自己看到的图片与大家一起分享了![url]http://mm-nn.com.cn/MM[/url]网[url]http://haotupic.cn/[/url]好图片网[url]http://www.picguan.cn/[/url]美女图片馆[url]http://www.nvyoou.cn/[/url]女友网[url]http://www.soft…