Java实现屏幕截屏
生活随笔
收集整理的這篇文章主要介紹了
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实现屏幕截屏的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: selenium2java 截图保存桌面
- 下一篇: GitHub上热门的Java开源项目