Java实现屏幕截屏
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实现屏幕截屏相关推荐
- JavaCV音视频开发宝典:JavaCV使用gdigrab方式实现windows录屏(windows屏幕画面抓取/采集,可实现高帧率屏幕截屏、录屏功能)
<JavaCV音视频开发宝典>专栏目录导航 <JavaCV音视频开发宝典>专栏介绍和目录 前言 本系列文章前面内容基本覆盖了推流拉流等内容,屏幕截屏之前也写过,只不过是基于ja ...
- android屏幕截屏
Android5.0之前如果希望截图屏幕需要系统权限root,在5.0之后开发了接口android.media.projection,使用该接口,第三方程序无需root权限也可以直接进行屏幕截图操作了 ...
- android webview 截图,Android获取webView快照与屏幕截屏的方法 -电脑资料
前段时间做的一个书店项目其阅读模块中用到了WebView + js,今天把WebView这块用到的几个特性记录下, 其主要用到了webView的快照与屏幕的截屏.部分代码如下: [html] /** ...
- ios xcode真机调试获取屏幕截屏
ios xcode真机调试获取屏幕截屏 非常多时候我们须要在调试的过程中把手机屏幕截图发给其它人看,在android开发中我们能够非常方便的截图保存.而xcode开发ios的时候发现这个需求却如此困难 ...
- 【常用命令】一键屏幕截屏操作
一键屏幕截屏操作tips Windows bat 思路 代码范例 Linux shell 操作视频 督促自己学习总结,特用文章的形式记录下来,共同进步 工作中很多命令都可以用这样的脚本实现,提高我们的 ...
- 绿色开源的屏幕/截屏OCR软件Capture2Text
近日发现一个比较好的绿色开源的屏幕/截屏OCR软件--Capture2Text 官网说明:http://capture2text.sourceforge.net/ 项目地址:https://sourc ...
- 计算机截屏法律措施,电脑屏幕截屏【处置方法】
喜欢使用电脑的小伙伴们一般都会遇到win7系统电脑屏幕截屏的问题,突然遇到win7系统电脑屏幕截屏的问题就不知道该怎么办了,其实win7系统电脑屏幕截屏的解决方法非常简单,按照 1:首先说的一种是电脑 ...
- iOS中的截屏(屏幕截屏及scrollView或tableView的全部截屏)
iOS中的截屏(屏幕截屏及scrollView或tableView的全部截屏) 2017.03.16 12:18* 字数 52 阅读 563评论 4喜欢 2 1. 截取屏幕尺寸大小的图片并保存至相册 ...
- android 关于屏幕截屏的几种办法
年末较闲,就上个星期查找各方面的资料关于android截图事情,自已也测试一些代码,已改改进或者优化.接下来进行总结一下.其实,如果真正android系统截屏是需要root权限的.但要用户使用都roo ...
最新文章
- 四月青少年编程组队学习(图形化四级)Task05
- cocos2dx - Lua 语言
- 联想、戴尔、惠普等笔记本预装膨胀件 存在安全隐患
- python string模块安装_python String模块-阿里云开发者社区
- 《Artifact》的得与失:成功的游戏工业品,却与主流背道而驰
- 运行命令对电脑的操作(Windows + R)
- BSP for good 3d engine
- php比例算法,图片比例转换算法
- JDK8新特性(六)之Stream流的forEach()方法
- Cocos2dx 之 PhysicsHandler 简单实现
- Sublime Text 3 全程详细图文使用教程
- 网络协议TCP/IP、IPX/SPX、NETBEUI简介
- 智能名片小程序创建名片页的表单校验使用正则表达式整理
- 银行家算法(C++实现)
- 小程序提示 网络异常 Network Anomalies
- ORACLE分配DBA权限
- 5214页PDF的进阶架构师学习笔记,阿里巴巴内部Jetpack宝典意外流出
- ajax type是get请求,jQuery的Ajax请求数据时type无法使用GET
- Flink DataStream时间水印机制
- Ubuntu 16.04 小键盘数字键盘开机自动启动