Java实现屏幕截屏功能

程序运行后的截图:

先测试一下功能:
截图过程对界面的捕捉:

双击保存后的显示界面:

后续的步骤就自己去尝试吧,这里给出了简单的测试过程。

程序结构:

代码部分显示:

CaptureScreen.java

/*** CaptureScreen.java*/
import java.awt.*;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.event.*;
import javax.swing.*;
import java.io.*;
import javax.imageio.*;
import java.awt.image.*;public class CaptureScreen extends JFrame implements ActionListener {private JButton start,cancel;private JPanel c;private BufferedImage get;private JTabbedPane jtp;//一个放置很多份图片private int index;//一个一直会递增的索引,用于标认图片private JRadioButton java,system;//JAVA界面,系统界面/** Creates a new instance of CaptureScreen */public CaptureScreen() {super("屏幕截取");try{UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());}catch(Exception exe){exe.printStackTrace();}initWindow();initOther();}private void initOther(){jtp=new JTabbedPane(JTabbedPane.TOP,JTabbedPane.SCROLL_TAB_LAYOUT);}private void initWindow(){start=new JButton("开始截取");cancel=new JButton("退出");start.addActionListener(this);cancel.addActionListener(this);JPanel buttonJP=new JPanel();c=new JPanel(new BorderLayout());JLabel jl=new JLabel("屏幕截取", JLabel.CENTER);jl.setFont(new Font("黑体",Font.BOLD,40));jl.setForeground(Color.RED);c.add(jl,BorderLayout.CENTER);buttonJP.add(start);buttonJP.add(cancel);buttonJP.setBorder(BorderFactory.createTitledBorder("公共操作区"));JPanel jp=new JPanel();//放置两个单选按钮的面板jp.add(java=new JRadioButton("java界面"));jp.add(system=new JRadioButton("系统界面",true));java.addActionListener(this);system.addActionListener(this);jp.setBorder(BorderFactory.createTitledBorder("界面风格"));ButtonGroup bg=new ButtonGroup();bg.add(java);bg.add(system);JPanel all=new JPanel();all.add(jp);all.add(buttonJP);this.getContentPane().add(c,BorderLayout.CENTER);this.getContentPane().add(all,BorderLayout.SOUTH);this.setSize(500,400);this.setLocationRelativeTo(null);this.setVisible(true);this.setAlwaysOnTop(true);this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);}private void updates(){this.setVisible(true);if(get!=null){//如果索引是0,则表示一张图片都没有被加入过,//则要清除当前的东西,重新把tabpane放进来if(index==0){c.removeAll();c.add(jtp,BorderLayout.CENTER);}else{//否则的话,直接对tabpane添加面板就可以了//就什么都不用做了}PicPanel pic=new PicPanel(get);jtp.addTab("图片"+(++index),pic);jtp.setSelectedComponent(pic);SwingUtilities.updateComponentTreeUI(c); // 调整LookAndFeel(javax.swing)}}private void doStart(){try{this.setVisible(false);Thread.sleep(500);//睡500毫秒是为了让主窗完全不见Robot ro=new Robot(); // (通过本地操作)控制鼠标、键盘等实际输入源(java.awt)Toolkit tk=Toolkit.getDefaultToolkit(); // AWT组件的抽象父类(java.awt)Dimension di=tk.getScreenSize();Rectangle rec=new Rectangle(0,0,di.width,di.height);BufferedImage bi=ro.createScreenCapture(rec);JFrame jf=new JFrame();Temp temp=new Temp(jf,bi,di.width,di.height); // 自定义的Temp类的对象jf.getContentPane().add(temp,BorderLayout.CENTER);jf.setUndecorated(true);jf.setSize(di);jf.setVisible(true);jf.setAlwaysOnTop(true);} catch(Exception exe){exe.printStackTrace();}}/***公用的处理保存图片的方法*/public  void doSave(BufferedImage get){try{if(get==null){JOptionPane.showMessageDialog(this, "图片不能为空!!", "错误", JOptionPane.ERROR_MESSAGE);return;}JFileChooser jfc=new JFileChooser(".");jfc.addChoosableFileFilter(new GIFfilter());jfc.addChoosableFileFilter(new BMPfilter());jfc.addChoosableFileFilter(new JPGfilter());jfc.addChoosableFileFilter(new PNGfilter());int i=jfc.showSaveDialog(this);if(i==JFileChooser.APPROVE_OPTION){File file=jfc.getSelectedFile();String about="PNG";String ext=file.toString().toLowerCase();javax.swing.filechooser.FileFilter ff=jfc.getFileFilter();if(ff instanceof JPGfilter){if(!ext.endsWith(".jpg")){String ns=ext+".jpg";file=new File(ns);about="JPG";}} else if(ff instanceof PNGfilter){if(!ext.endsWith(".png")){String ns=ext+".png";file=new File(ns);about="PNG";}}else if(ff instanceof BMPfilter){if(!ext.endsWith(".bmp")){String ns=ext+".bmp";file=new File(ns);about="BMP";}}else if(ff instanceof GIFfilter){if(!ext.endsWith(".gif")){String ns=ext+".gif";file=new File(ns);about="GIF";}}if(ImageIO.write(get,about,file)){JOptionPane.showMessageDialog(this,"保存成功!");} elseJOptionPane.showMessageDialog(this,"保存失败!");}} catch(Exception exe){exe.printStackTrace();}}/** *公共的处理把当前的图片加入剪帖板的方法*/public void doCopy(final BufferedImage image){try{if(get==null){JOptionPane.showMessageDialog(this,"图片不能为空!!","错误",JOptionPane.ERROR_MESSAGE);return;} // java.awt.datatransfer(接口)Transferable trans = new Transferable(){ // 内部类public DataFlavor[] getTransferDataFlavors() {return new DataFlavor[] { DataFlavor.imageFlavor };}public boolean isDataFlavorSupported(DataFlavor flavor) {return DataFlavor.imageFlavor.equals(flavor);}public Object getTransferData(DataFlavor flavor)throws UnsupportedFlavorException, IOException {if(isDataFlavorSupported(flavor))return image;throw new UnsupportedFlavorException(flavor);}};Toolkit.getDefaultToolkit().getSystemClipboard().setContents(trans, null);JOptionPane.showMessageDialog(this,"已复制到系统粘帖板!!");}catch(Exception exe){exe.printStackTrace();JOptionPane.showMessageDialog(this,"复制到系统粘帖板出错!!","错误",JOptionPane.ERROR_MESSAGE);}}//处理关闭事件private void doClose(Component c){jtp.remove(c);c=null;System.gc();}public void actionPerformed(ActionEvent ae){Object source=ae.getSource();if(source==start){doStart();} else if(source==cancel){System.exit(0);}else if(source==java){ // 金属外观try{UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());SwingUtilities.updateComponentTreeUI(this);}catch(Exception exe){exe.printStackTrace();}}else if(source==system){ // 本地外观try{UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());SwingUtilities.updateComponentTreeUI(this);}catch(Exception exe){exe.printStackTrace();}}}//一个内部类,它表示一个面板,一个可以被放进tabpane的面板//也有自己的一套处理保存和复制的方法private class PicPanel extends JPanel implements ActionListener{JButton save,copy,close;//表示保存,复制,关闭的按钮BufferedImage get;//得到的图片public PicPanel(BufferedImage get){super(new BorderLayout());this.get=get;initPanel();}private void initPanel(){save=new JButton("保存(S)");copy=new JButton("复制到剪帖板(C)");close=new JButton("关闭(X)");save.setMnemonic('S');copy.setMnemonic('C');close.setMnemonic('X');JPanel buttonPanel=new JPanel();buttonPanel.add(copy);buttonPanel.add(save);buttonPanel.add(close);JLabel icon=new JLabel(new ImageIcon(get));this.add(new JScrollPane(icon),BorderLayout.CENTER);this.add(buttonPanel,BorderLayout.SOUTH);save.addActionListener(this);copy.addActionListener(this);close.addActionListener(this);}public void actionPerformed(ActionEvent e) {Object source=e.getSource();if(source==save){doSave(get);}else if(source==copy){doCopy(get);}else if(source==close){get=null;doClose(this);}}}//保存BMP格式的过滤器private class BMPfilter extends javax.swing.filechooser.FileFilter{public BMPfilter(){}public boolean accept(File file){if(file.toString().toLowerCase().endsWith(".bmp")||file.isDirectory()){return true;} elsereturn false;}public String getDescription(){return "*.BMP(BMP图像)";}}//保存JPG格式的过滤器private class JPGfilter extends javax.swing.filechooser.FileFilter{public JPGfilter(){}public boolean accept(File file){if(file.toString().toLowerCase().endsWith(".jpg")||file.isDirectory()){return true;} elsereturn false;}public String getDescription(){return "*.JPG(JPG图像)";}}//保存GIF格式的过滤器private class GIFfilter extends javax.swing.filechooser.FileFilter{public GIFfilter(){}public boolean accept(File file){if(file.toString().toLowerCase().endsWith(".gif")||file.isDirectory()){return true;} elsereturn false;}public String getDescription(){return "*.GIF(GIF图像)";}}//保存PNG格式的过滤器private class PNGfilter extends javax.swing.filechooser.FileFilter{public boolean accept(File file){if(file.toString().toLowerCase().endsWith(".png")||file.isDirectory()){return true;} elsereturn false;}public String getDescription(){return "*.PNG(PNG图像)";}}//一个临时类,用于显示当前的屏幕图像private class Temp extends JPanel implements MouseListener,MouseMotionListener{private BufferedImage bi;private int width,height;private int startX,startY,endX,endY,tempX,tempY;private JFrame jf;private Rectangle select=new Rectangle(0,0,0,0);//表示选中的区域private Cursor cs=new Cursor(Cursor.CROSSHAIR_CURSOR);//表示一般情况下的鼠标状态(十字线)private States current=States.DEFAULT;// 表示当前的编辑状态private Rectangle[] rec;//表示八个编辑点的区域//下面四个常量,分别表示谁是被选中的那条线上的端点public static final int START_X=1;public static final int START_Y=2;public static final int END_X=3;public static final int END_Y=4;private int currentX,currentY;//当前被选中的X和Y,只有这两个需要改变private Point p=new Point();//当前鼠标移的地点private boolean showTip=true;//是否显示提示.如果鼠标左键一按,则提示就不再显示了public Temp(JFrame jf,BufferedImage bi,int width,int height){this.jf=jf;this.bi=bi;this.width=width;this.height=height;this.addMouseListener(this);this.addMouseMotionListener(this);initRecs();}private void initRecs(){rec=new Rectangle[8];for(int i=0;i<rec.length;i++){rec[i]=new Rectangle();}}public void paintComponent(Graphics g){g.drawImage(bi,0,0,width,height,this);g.setColor(Color.RED);g.drawLine(startX,startY,endX,startY);g.drawLine(startX,endY,endX,endY);g.drawLine(startX,startY,startX,endY);g.drawLine(endX,startY,endX,endY);int x=startX<endX?startX:endX;int y=startY<endY?startY:endY;select=new Rectangle(x,y,Math.abs(endX-startX),Math.abs(endY-startY));int x1=(startX+endX)/2;int y1=(startY+endY)/2;g.fillRect(x1-2,startY-2,5,5);g.fillRect(x1-2,endY-2,5,5);g.fillRect(startX-2,y1-2,5,5);g.fillRect(endX-2,y1-2,5,5);g.fillRect(startX-2,startY-2,5,5);g.fillRect(startX-2,endY-2,5,5);g.fillRect(endX-2,startY-2,5,5);g.fillRect(endX-2,endY-2,5,5);rec[0]=new Rectangle(x-5,y-5,10,10);rec[1]=new Rectangle(x1-5,y-5,10,10);rec[2]=new Rectangle((startX>endX?startX:endX)-5,y-5,10,10);rec[3]=new Rectangle((startX>endX?startX:endX)-5,y1-5,10,10);rec[4]=new Rectangle((startX>endX?startX:endX)-5,(startY>endY?startY:endY)-5,10,10);rec[5]=new Rectangle(x1-5,(startY>endY?startY:endY)-5,10,10);rec[6]=new Rectangle(x-5,(startY>endY?startY:endY)-5,10,10);rec[7]=new Rectangle(x-5,y1-5,10,10);if(showTip){g.setColor(Color.CYAN);g.fillRect(p.x,p.y,170,20);g.setColor(Color.RED);g.drawRect(p.x,p.y,170,20);g.setColor(Color.BLACK);g.drawString("请按住鼠标左键不放选择截图区",p.x,p.y+15);}}//根据东南西北等八个方向决定选中的要修改的X和Y的座标private void initSelect(States state){switch(state){case DEFAULT:currentX=0;currentY=0;break;case EAST:currentX=(endX>startX?END_X:START_X);currentY=0;break;case WEST:currentX=(endX>startX?START_X:END_X);currentY=0;break;case NORTH:currentX=0;currentY=(startY>endY?END_Y:START_Y);break;case SOUTH:currentX=0;currentY=(startY>endY?START_Y:END_Y);break;case NORTH_EAST:currentY=(startY>endY?END_Y:START_Y);currentX=(endX>startX?END_X:START_X);break;case NORTH_WEST:currentY=(startY>endY?END_Y:START_Y);currentX=(endX>startX?START_X:END_X);break;case SOUTH_EAST:currentY=(startY>endY?START_Y:END_Y);currentX=(endX>startX?END_X:START_X);break;case SOUTH_WEST:currentY=(startY>endY?START_Y:END_Y);currentX=(endX>startX?START_X:END_X);break;default:currentX=0;currentY=0;break;}}public void mouseMoved(MouseEvent me){doMouseMoved(me);initSelect(current); // current:当前状态(state)if(showTip){p=me.getPoint();repaint();}}//特意定义一个方法处理鼠标移动,是为了每次都能初始化一下所要选择的区域private void doMouseMoved(MouseEvent me){if(select.contains(me.getPoint())){this.setCursor(new Cursor(Cursor.MOVE_CURSOR));current=States.MOVE;} else{States[] st=States.values();for(int i=0;i<rec.length;i++){if(rec[i].contains(me.getPoint())){current=st[i];this.setCursor(st[i].getCursor());return;}}this.setCursor(cs);current=States.DEFAULT;}}public void mouseExited(MouseEvent me){}public void mouseEntered(MouseEvent me){}public void mouseDragged(MouseEvent me){int x=me.getX();int y=me.getY();// 分别处理一系列的(光标)状态(枚举值)if(current==States.MOVE){startX+=(x-tempX);startY+=(y-tempY);endX+=(x-tempX);endY+=(y-tempY);tempX=x;tempY=y;}else if(current==States.EAST||current==States.WEST){if(currentX==START_X){startX+=(x-tempX);tempX=x;}else{endX+=(x-tempX);tempX=x;}}else if(current==States.NORTH||current==States.SOUTH){if(currentY==START_Y){startY+=(y-tempY);tempY=y;}else{endY+=(y-tempY);tempY=y;}}else if(current==States.NORTH_EAST||current==States.NORTH_EAST||current==States.SOUTH_EAST||current==States.SOUTH_WEST){if(currentY==START_Y){startY+=(y-tempY);tempY=y;}else{endY+=(y-tempY);tempY=y;}if(currentX==START_X){startX+=(x-tempX);tempX=x;}else{endX+=(x-tempX);tempX=x;}                }else{startX=tempX;startY=tempY;endX=me.getX();endY=me.getY();}this.repaint();}public void mousePressed(MouseEvent me){showTip=false;tempX=me.getX();tempY=me.getY();}public void mouseReleased(MouseEvent me){if(me.isPopupTrigger()){ // 右键if(current==States.MOVE){showTip=true;p=me.getPoint();startX=0;startY=0;endX=0;endY=0;repaint();} else{ // 普通情况jf.dispose();updates();}}}public void mouseClicked(MouseEvent me){if(me.getClickCount()==2){//Rectangle rec=new Rectangle(startX,startY,Math.abs(endX-startX),Math.abs(endY-startY));Point p=me.getPoint();if(select.contains(p)){if(select.x+select.width<this.getWidth()&&select.y+select.height<this.getHeight()){get=bi.getSubimage(select.x,select.y,select.width,select.height);jf.dispose();updates();}else{int wid=select.width,het=select.height;if(select.x+select.width>=this.getWidth()){wid=this.getWidth()-select.x;}if(select.y+select.height>=this.getHeight()){het=this.getHeight()-select.y;}get=bi.getSubimage(select.x,select.y,wid,het);jf.dispose();updates();}}}}}public static void main(String args[]) {SwingUtilities.invokeLater(new Runnable(){public void run(){new CaptureScreen();}});}
}//一些表示状态的枚举
enum States{NORTH_WEST(new Cursor(Cursor.NW_RESIZE_CURSOR)),//表示西北角NORTH(new Cursor(Cursor.N_RESIZE_CURSOR)),NORTH_EAST(new Cursor(Cursor.NE_RESIZE_CURSOR)),EAST(new Cursor(Cursor.E_RESIZE_CURSOR)),SOUTH_EAST(new Cursor(Cursor.SE_RESIZE_CURSOR)),SOUTH(new Cursor(Cursor.S_RESIZE_CURSOR)),SOUTH_WEST(new Cursor(Cursor.SW_RESIZE_CURSOR)),WEST(new Cursor(Cursor.W_RESIZE_CURSOR)),MOVE(new Cursor(Cursor.MOVE_CURSOR)),DEFAULT(new Cursor(Cursor.DEFAULT_CURSOR));private Cursor cs;States(Cursor cs){this.cs=cs;}public Cursor getCursor(){return cs;}
}

云链接:Java之屏幕截图
提取码:cooy

Java实现屏幕截屏相关推荐

  1. JavaCV音视频开发宝典:JavaCV使用gdigrab方式实现windows录屏(windows屏幕画面抓取/采集,可实现高帧率屏幕截屏、录屏功能)

    <JavaCV音视频开发宝典>专栏目录导航 <JavaCV音视频开发宝典>专栏介绍和目录 前言 本系列文章前面内容基本覆盖了推流拉流等内容,屏幕截屏之前也写过,只不过是基于ja ...

  2. android屏幕截屏

    Android5.0之前如果希望截图屏幕需要系统权限root,在5.0之后开发了接口android.media.projection,使用该接口,第三方程序无需root权限也可以直接进行屏幕截图操作了 ...

  3. android webview 截图,Android获取webView快照与屏幕截屏的方法 -电脑资料

    前段时间做的一个书店项目其阅读模块中用到了WebView + js,今天把WebView这块用到的几个特性记录下, 其主要用到了webView的快照与屏幕的截屏.部分代码如下: [html] /** ...

  4. ios xcode真机调试获取屏幕截屏

    ios xcode真机调试获取屏幕截屏 非常多时候我们须要在调试的过程中把手机屏幕截图发给其它人看,在android开发中我们能够非常方便的截图保存.而xcode开发ios的时候发现这个需求却如此困难 ...

  5. 【常用命令】一键屏幕截屏操作

    一键屏幕截屏操作tips Windows bat 思路 代码范例 Linux shell 操作视频 督促自己学习总结,特用文章的形式记录下来,共同进步 工作中很多命令都可以用这样的脚本实现,提高我们的 ...

  6. 绿色开源的屏幕/截屏OCR软件Capture2Text

    近日发现一个比较好的绿色开源的屏幕/截屏OCR软件--Capture2Text 官网说明:http://capture2text.sourceforge.net/ 项目地址:https://sourc ...

  7. 计算机截屏法律措施,电脑屏幕截屏【处置方法】

    喜欢使用电脑的小伙伴们一般都会遇到win7系统电脑屏幕截屏的问题,突然遇到win7系统电脑屏幕截屏的问题就不知道该怎么办了,其实win7系统电脑屏幕截屏的解决方法非常简单,按照 1:首先说的一种是电脑 ...

  8. iOS中的截屏(屏幕截屏及scrollView或tableView的全部截屏)

    iOS中的截屏(屏幕截屏及scrollView或tableView的全部截屏) 2017.03.16 12:18* 字数 52 阅读 563评论 4喜欢 2 1. 截取屏幕尺寸大小的图片并保存至相册 ...

  9. android 关于屏幕截屏的几种办法

    年末较闲,就上个星期查找各方面的资料关于android截图事情,自已也测试一些代码,已改改进或者优化.接下来进行总结一下.其实,如果真正android系统截屏是需要root权限的.但要用户使用都roo ...

最新文章

  1. 四月青少年编程组队学习(图形化四级)Task05
  2. cocos2dx - Lua 语言
  3. 联想、戴尔、惠普等笔记本预装膨胀件 存在安全隐患
  4. python string模块安装_python String模块-阿里云开发者社区
  5. 《Artifact》的得与失:成功的游戏工业品,却与主流背道而驰
  6. 运行命令对电脑的操作(Windows + R)
  7. BSP for good 3d engine
  8. php比例算法,图片比例转换算法
  9. JDK8新特性(六)之Stream流的forEach()方法
  10. Cocos2dx 之 PhysicsHandler 简单实现
  11. Sublime Text 3 全程详细图文使用教程
  12. 网络协议TCP/IP、IPX/SPX、NETBEUI简介
  13. 智能名片小程序创建名片页的表单校验使用正则表达式整理
  14. 银行家算法(C++实现)
  15. 小程序提示 网络异常 Network Anomalies
  16. ORACLE分配DBA权限
  17. 5214页PDF的进阶架构师学习笔记,阿里巴巴内部Jetpack宝典意外流出
  18. ajax type是get请求,jQuery的Ajax请求数据时type无法使用GET
  19. Flink DataStream时间水印机制
  20. Ubuntu 16.04 小键盘数字键盘开机自动启动

热门文章

  1. 灵活就业人员压力好大,不知道该不该继续交社保?
  2. 云产品学习之路(阿里云01)阿里云rds数据库导出
  3. (已解决)Android Studio 模拟器连接不上问题
  4. HDU 1234 JAVA
  5. 数据可视化(箱线图、直方图、散点图、联合分布图)
  6. 浅析安全架构中遇到的问题
  7. 欣赏 Pianissimo!!! 钢琴演奏会
  8. android相片拼板源码,实现仿微信拍照和选取相片(转自网络)
  9. java中文逗号替换英文逗号
  10. 霹雳吧啦Wz语义分割学习笔记P2