Java-JAVA 实现屏幕截图

Java-JAVA 实现屏幕截图

偏爱自由 发布于 2017-09-01 字数 6607 浏览 1121 回复 4

今天看到有人提问用PHP如何实现屏幕截图,我感觉应该是3种方法: 1. 调用COM;2. 使用php-GTK库;3. 前端使用FLASH

而对于java呢,我于两三年前玩过,先列出我的实现,此处仅仅列出简单的代码,更加具体的效果参见我的博客: http://vb2005xu.iteye.com/blog/316320

这只是一种思路,如果大家感兴趣,请在下面列出诸位的方案,呵呵

package cn.iamsese.prj.db.helper;
import java.awt.AWTException;
import java.awt.Dimension;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Date;

import javax.imageio.ImageIO;

interface ImageType {
public final static String JPG = "JPG" ;
public final static String PNG = "PNG" ;
public final static String GIF = "GIF" ;
}

/**
* 屏幕截取 类
* 参考 http://www.iteye.com/topic/289052 实现
* cn.iamsese.prj.db.helper
* Author: vb2005xu [JAVA菜鸟]
*/
public class ScreenDumpHelper {
/** ScreenDumpHelper 静态对象*/
private static ScreenDumpHelper defaultScreenDumpHelper ;
/**
* 返回 ScreenDumpHelper 类的 单态实例
* @return ScreenDumpHelper
*/
public static ScreenDumpHelper getDefaultScreenDumpHelper(){
if (defaultScreenDumpHelper == null)
return new ScreenDumpHelper();
return defaultScreenDumpHelper ;
}
/**
* 构造函数中设置 截屏区域的默认值 -- 缺省为全屏
*/
public ScreenDumpHelper(){
Dimension dime = Toolkit.getDefaultToolkit().getScreenSize();
this.setScreenArea(new Rectangle(dime));
}

/**
*设置截屏的范围
*/
private Rectangle screenArea ;
public Rectangle getScreenArea() {
return this.screenArea;
}
public void setScreenArea(Rectangle screenArea) {
this.screenArea = screenArea;
}
public void setScreenArea(int x, int y , int width, int height) {
this.screenArea = new Rectangle(x,y,width,height);
}

/**
* 返回一个 BufferedImage
* @return
* @throws AWTException
*/
private BufferedImage getBufferedImage() throws AWTException{
BufferedImage imgBuf = null ;;
imgBuf = ( new Robot() ).createScreenCapture(this.getScreenArea());
return imgBuf ;
}

/**
* 将 图像数据写到 输出流中去,方便再处理
* @param fileFormat
* @param output
* @return
*/
public boolean saveToOutputStream(String fileFormat,OutputStream output){
try {
ImageIO.write(this.getBufferedImage(), fileFormat, output) ;
} catch (AWTException e) {
return false ;
//e.printStackTrace();
} catch (IOException e) {
return false ;
//e.printStackTrace();
}
return true ;
}

/**
* 根据文件格式 返回随机文件名称
* @param fileFormat
* @return
*/
public String getRandomFileName(String fileFormat){
return "screenDump_" + (new Date()).getTime() + "." + fileFormat ;
}

/**
* 抓取 指定区域的截图 到指定格式的文件中 -- 这个函数是核心,所有的都是围绕它来展开的
* * 图片的编码并不是以后缀名来判断:
* 比如s.jpg 如果其采用png编码,那么这个图片就是png格式的
* @param fileName
* @param fileFormat
* @return boolean
*/
public boolean saveToFile(String fileName,String fileFormat){
if (fileName == null)
fileName = getRandomFileName(fileFormat) ;
try {
FileOutputStream fos = new FileOutputStream(fileName);
this.saveToOutputStream(fileFormat, fos);
} catch (FileNotFoundException e) {
System.out.println("非常规文件或不能创建抑或覆盖此文件: " + fileName);
e.printStackTrace();
}
return true ;
}

/**
* 抓取 指定 Rectangle 区域的截图 到指定格式的文件中
* @param fileName
* @param fileFormat
* @param screenArea
* @return
*/
public boolean saveToFile(String fileName,String fileFormat,Rectangle screenArea){
this.setScreenArea(screenArea);
return this.saveToFile(fileName,fileFormat);
}
/**
* 抓取 指定区域的截图 到指定格式的文件中
* @param fileName
* @param fileFormat
* @param x
* @param y
* @param width
* @param height
*/
public boolean saveToFile(String fileName,String fileFormat,int x, int y , int width, int height){
this.setScreenArea(x,y,width,height);
return this.saveToFile(fileName, fileFormat);
}

/**
* 将截图使用 JPG 编码
* @param fileName
*/
public void saveToJPG(String fileName){
this.saveToFile(fileName, ImageType.JPG);
}
public void saveToJPG(String fileName,Rectangle screenArea){
this.saveToFile(fileName, ImageType.JPG,screenArea);
}
public void saveToJPG(String fileName,int x, int y , int width, int height){
this.saveToFile(fileName, ImageType.JPG,x,y,width,height);
}

/**
* 将截图使用 PNG 编码
* @param fileName
*/
public void saveToPNG(String fileName){
this.saveToFile(fileName, ImageType.PNG);
}
public void saveToPNG(String fileName,Rectangle screenArea){
this.saveToFile(fileName, ImageType.PNG,screenArea);
}
public void saveToPNG(String fileName,int x, int y , int width, int height){
this.saveToFile(fileName, ImageType.PNG,x,y,width,height);
}

public void saveToGIF(String fileName){
throw new UnsupportedOperationException("不支持保存到GIF文件");
//this.saveToFile(fileName, ImageType.GIF);
}


/**
* @param args
*/
public static void main(String[] args) {
for(int i = 0 ; i < 5 ; i ++)
ScreenDumpHelper.getDefaultScreenDumpHelper().saveToJPG(null,i*150,i*150,400,300);
}



}

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

归属感 2017-10-18 4 楼

额,我之前做过一个屏幕录像功能用过截图

 private void snapShot() {
try {
BufferedImage screenshot = new Robot().createScreenCapture(new Rectangle(0, 0,width, height));
String filename = tmpfile.get(currentFile).getAbsolutePath()+ File.separator + toString(serialnum) +"."+ format;
File image = new File(filename);
ImageIO.write(screenshot, format, image);
System.out.println("INFO:文件夹"+currentFile+"内第"+serialnum+"图片");
} catch (Exception ex) {
System.out.println(ex);
}
}

这只是个方法,format是图片格式,currentFile是文件夹。

总之Java截屏的一般方法就是这个。话说Java截屏的效率其实并不是很好,我21寸的显示器截全屏的话需要200+ms,不知道各位有没有一些好的优化方法,请多多指教

浮生未歇 2017-09-26 3 楼

既然是JAVA程序员,还用PHP-GTK库,有点滑稽了。JAVA更擅长这类事
JAVA里有个robot类,拿来用就可以了。另外也可以直接调COM。
可参考 http://code.google.com/p/greenvm 下载列表那有

夜无邪 2017-09-16 2 楼

大家帮忙看看这个程序,搞了一天了很纠结,现在程序可以运行可还是调不出屏幕截图时的红色线框,还有保存的时候格式本来是固定jpg的,可现在还是得手动输入才可以。。

 import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import javax.swing.*;

import java.io.*;
import javax.imageio.ImageIO;
public class jietu extends JFrame implements ActionListener{

/**
* @param args
*/
Checkbox check=new Checkbox("隐藏窗口");
JButton btnshow=new JButton("截取");
JButton fullscreen=new JButton("全屏");
JButton btnclose=new JButton("关闭");
pictrue p=new pictrue();
public static boolean fshow;
jietu(){
super("截图工具");
this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);//能关闭窗口
Container con=this.getContentPane();

btnshow.addActionListener(this);//添加事件
fullscreen.addActionListener(this);
btnclose.addActionListener(this);

con.setLayout(new FlowLayout());//布局方式

con.add(btnshow);//添加控件
con.add(fullscreen);
con.add(btnclose);
con.add(check);

this.pack(); //自动适应窗口大小
}

public static void main(String[] args) {
jietu j=new jietu();
j.setVisible(true);//显示窗口
}

public void actionPerformed(ActionEvent e) {
// TODO 自动生成方法存根
if(check.getState()){
this.setVisible(false); //判断窗口是否隐藏
fshow=true;
}
else{
this.setVisible(true);
fshow=false;
}

if(e.getSource()==btnshow){ //截图按钮事件
try{
Thread.sleep(300);
pictrue p=new pictrue();
p.setVisible(true);
}
catch(Exception ex){

}
}
if(e.getSource()==fullscreen){ //全屏按钮事件
try{
Thread.sleep(300);
pictrue p=new pictrue();
p.imagefile();
}
catch(Exception ex){

}

}
if(e.getSource()==btnclose){ //关闭窗口
System.exit(0);
}
}
}

class pictrue extends JFrame implements MouseMotionListener,MouseListener{

int startx;
int starty;
int endx;
int endy;
int width;
int height;
boolean mouse=false;

Toolkit t=this.getToolkit().getDefaultToolkit(); //工具包 能够找出整个屏幕的大小
Robot robot; //截取屏幕的类
BufferedImage image;

pictrue(){
super("图片框");
this.first();
this.addMouseMotionListener(this); //给窗口鼠标添加事件
this.addMouseListener(this);//给窗口鼠标添加事件

this.setUndecorated(true); //显示没有标题栏
this.setSize(t.getScreenSize().width,t.getScreenSize().height);//将窗口设置到屏幕的大小
}
public void first(){
try{
robot=new Robot();
image=robot.createScreenCapture(new Rectangle(t.getScreenSize())); // 把整个屏幕截下来
}
catch(Exception ex){

}
}
public void paint(Graphics g){

g.drawImage(image, 0, 0, this);//将图片填充到窗口

}

public void update(Graphics g){
paint(g);
if(mouse){
g.setColor(Color.RED);
g.drawRect(startx,starty,endx-startx, endy-starty); //绘制截取框 就是那条红线
}

}
public void mouseMoved(MouseEvent e){
}

public void mouseDragged(MouseEvent e) {
// TODO 自动生成方法存根
endx=e.getX();
endy=e.getY();
this.repaint();
}
public void mouseClicked(MouseEvent e) {
// TODO 自动生成方法存根

}
public void mouseEntered(MouseEvent e) {
// TODO 自动生成方法存根

}
public void mouseExited(MouseEvent e) {
// TODO 自动生成方法存根

}
public void mousePressed(MouseEvent e) {
// TODO 自动生成方法存根
mouse=true;
startx=e.getX();
starty=e.getY();
}
public void mouseReleased(MouseEvent e) {
// TODO 自动生成方法存根
this.setVisible(false);
if(mouse){
endx=e.getX();
endy=e.getY();
image=robot.createScreenCapture(new Rectangle(startx,starty,endx-startx, endy-starty));
this.imagefile();
}

mouse=false;
}
public void imagefile(){
JFileChooser filesave=new JFileChooser("d:");
try{
Thread.sleep(200);
int v=filesave.showSaveDialog(this);
if(v==JFileChooser.APPROVE_OPTION){

ImageIO.write(image,"jpg",new File(filesave.getSelectedFile().getPath()));
JOptionPane.showMessageDialog(this,filesave.getSelectedFile());
}
}
catch(Exception ex){
}

if(jietu.fshow){
jietu j=new jietu();
j.setVisible(true);
}
}
}

浮生未歇 2017-09-09 1 楼

import java.awt.*;
import java.awt.image.*;
import java.io.*;
import javax.imageio.*;

public class RobotDemo {

private Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
private String imageFormat = "png";
private String fileName = "default";

public static void main(String[] args) {
RobotDemo r = new RobotDemo();
r.snapShot();
r.setImageFormat("jpeg");
r.snapShot();
}

/**
* 截图
*/
public void snapShot() {
try {
BufferedImage screen = (new Robot())
.createScreenCapture(new Rectangle(0, 0,
(int) d.getWidth(), (int) d.getHeight()));
String name = this.fileName + "." + this.imageFormat;
File f = new File(name);
ImageIO.write(screen, this.imageFormat, f);
System.out.println("截图成功!!!");
} catch (Exception e) {
// TODO: handle exception
System.out.println("截图失败!!!n" + e.getMessage());
}
}

/**
* 设置保存的文件名
*/
public void setFileName(String fileName) {
this.fileName = fileName;
}

/**
* 设置保存的图象的格式
*
* @param imageFormat
*/
public void setImageFormat(String imageFormat) {
this.imageFormat = imageFormat;
}

}