亚洲精品久久久中文字幕-亚洲精品久久片久久-亚洲精品久久青草-亚洲精品久久婷婷爱久久婷婷-亚洲精品久久午夜香蕉

您的位置:首頁技術文章
文章詳情頁

捕獲屏幕-編寫一個基于Java Robot類的屏幕捕獲工具

瀏覽:76日期:2024-06-05 17:05:22
內容: 摘要Java Fun and Games(Java娛樂和游戲)提供了通過Java的Robot類捕獲主屏幕設備的功能,并且可以將整個屏幕或者選定的一部分保存為jpeg文件。注意:現在你可以使用在線開發工具DevSquare編譯和運行Java Fun and Games中提供的applet。DevSquare入門請閱讀資源中提供的用戶向導。java.awt.Robot類為娛樂功能提供了一些有用的方法。其中一個包括了建立屏幕捕獲工具的功能。Java Fun and Games給出了一個使用Robot捕獲主屏幕設備內容的工具。這一部分從我以前的幾部分中分離出來了,因為它并不是集中在applet實現上。這篇文章以Swing應用的形式實現了屏幕捕獲工具。從GUI觀點介紹完這個應用之后,我將解釋實現的關鍵部分。版權聲明:任何獲得Matrix授權的網站,轉載時請務必保留以下作者信息和鏈接作者:Jeff Friesen;mydeman原文:http://www.javaworld.com/javaworld/jw-04-2006/jw-0424-funandgames.htmlMatrix:http://www.matrix.org.cn/resource/article/2006-09-15/Java+Robot_f9598e5e-445b-11db-af0b-0f766c077b58.html關鍵字:Java Robot;捕獲屏幕應用程序GUI我的Capture程序提供了一個圖形用戶界面(GUI,Graphic User Interface),通過它你可以選擇捕獲圖像的一部分,修剪圖像到選擇內容,以及將結果圖像保存為jpeg文件。圖1顯示了包含一個捕獲示例的Capture的GUI。 圖 1. 紅白相間的虛線所形成的矩形表示了當前選中的區域Capture的GUI由菜單欄和顯示捕獲圖像的可滾動窗口組成。如圖1所示,選擇矩形(通過拖拽鼠標)表示了捕獲圖形的一個矩形區域。菜單欄提供了File和Capture菜單:---File提供Save As…(另存為)和Exit(退出)菜單項,可以通過文件選擇器保存當前捕獲為一個jpeg文件,和退出Capture。盡管你可以直接選擇這些菜單項,但是你會發現使用它們的快捷鍵Alt-S和Alt-X會更加方便。---Capture提供Capture(捕獲)和Crop(修剪)菜單項,可以捕獲當前主屏幕設備的內容和修剪一個圖像為選擇矩形的內容。和File菜單項一樣,這些菜單項也有它們自己的方便的快捷鍵:Capture(Alt-C)和Crop(Alt-K)。應用實現有三個源文件來描述Capture的GUI:Capture.java(啟動應用程序和構造GUI)、ImageArea.java( 描述了一個用來顯示捕獲的內容的組件,你也可以在其中選擇捕獲的一部分或修剪捕獲的內容)和ImageFileFilter.java(限制文件選擇器的選擇是文件夾和jpeg文件)。在這一部分下面,我從這些源文件中摘錄了一些代碼片斷來說明Capture的工作過程。機器人屏幕捕獲為了使用Robot類捕獲屏幕,Capture必須先創建一個Robot對象。Capture類的public static void main(String [] args)方法嘗試調用Robot的public Robot()構造函數來創建這個對象。如果創建成功,就會返回一個針對主屏幕設備坐標系的Robot引用。如果平臺不支持低級控制(在沒有屏幕設備的環境這是成立的),將會拋出java.awt.AWTException。如果平臺不允許創建Robot對象就會拋出java.lang.SecurityException。但愿你不會再遇到其他異常。假設Robot對象已被創建,main()調用Capture類的構造函數創建一個GUI。作為GUI創建的一部分,Capture通過調用dimScreenSize = Toolkit.getDefaultToolkit().getScreenSize();獲得主屏幕設備的尺寸。因為用來顯示屏幕捕獲的內容的Robot的public BufferedImage createScreenCapture(Rectangle screenRect)方法,需要一個java.awt.Rectangle參數,所以構造函數通過rectScreenSize = new Rectangle(dimScreenSize);將java.awt.Dimension對象轉換為一個Rectangle對象。當Capture菜單項的動作監聽器被調用時,下面摘錄的Capture.java片斷就會調用createScreenCapture()。// Hide Capture's main window so that it does not appear in// the screen capture.setVisible (false);// Perform the screen capture.BufferedImage biScreen;biScreen = robot.createScreenCapture (rectScreenSize);// Show Capture's main window for continued user interaction.setVisible (true);// Update ImageArea component with the new image and adjust// the scrollbars.ia.setImage (biScreen);jsp.getHorizontalScrollBar ().setValue (0);jsp.getVerticalScrollBar ().setValue (0);你不希望Capture的GUI遮住你想要捕獲的任何內容。這就是為什么代碼中隱藏Capture GUI優先級高于完成捕獲。在獲取了包含屏幕像素copy的java.awt.image.BufferedImage后,代碼片斷顯示出GUI,并且通過圖像區域組件顯示出BufferedImage的內容。子圖像選擇當從一個捕獲的圖像中獲取子圖像時需要一個選擇矩形。ImageArea類提供代碼來創建、操作和繪制選擇矩形。如下面摘錄的ImageArea.java所示,這個類的構造函數以一個Rectangle實例創建選擇矩形,創建java.awt.BasicStoke和java.awt.GradientPaint對象定義了矩形的輪廓外觀(保持它與底層圖像分離),注冊鼠標和鼠標動作監聽器讓你能夠操作選擇矩形。// Create a selection Rectangle. It's better to create one Rectangle// here than a Rectangle each time paintComponent() is called, to reduce// unnecessary object creation.rectSelection = new Rectangle ();// Define the stroke for drawing selection rectangle outline.bs = new BasicStroke (5, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND, 0, new float [] { 12, 12 }, 0);// Define the gradient paint for coloring selection rectangle outline.gp = new GradientPaint (0.0f, 0.0f, Color.red, 1.0f, 1.0f, Color.white, true);// Install a mouse listener that sets things up for a selection drag.MouseListener ml;ml = new MouseAdapter () { public void mousePressed (MouseEvent e) { // When you start Capture, there is no captured image. // Therefore, it makes no sense to try and select a sub-image. // This is the reason for the if (image == null) test. if (image == null) return; destx = srcx = e.getX (); desty = srcy = e.getY (); repaint (); } };addMouseListener (ml);// Install a mouse motion listener to update the selection rectangle// during drag operations.MouseMotionListener mml;mml = new MouseMotionAdapter () { public void mouseDragged (MouseEvent e) { // When you start Capture, there is no captured image. // Therefore, it makes no sense to try and select a // sub-image. This is the reason for the if (image == null) // test. if (image == null) return; destx = e.getX (); desty = e.getY (); repaint (); } };addMouseMotionListener (mml);當按下鼠標時,鼠標事件處理器對相同的橫向鼠標坐標設置destx和srcx,對于縱向鼠標坐標亦是如此。源變量和目標變量同樣表示哪些顯示的選擇矩形應該被移除了。它通過調用repaint(),導致public void paintComponent(Graphics g)被調用。這個方法將srcx和srcy分別與destx和desty相比較,如果他們不同,就繪制一個選擇矩形:// Draw the selection rectangle if present.if (srcx != destx || srcy != desty){ // Compute upper-left and lower-right coordinates for selection // rectangle corners. int x1 = (srcx < destx) ? srcx : destx; int y1 = (srcy < desty) ? srcy : desty; int x2 = (srcx> destx) ? srcx : destx; int y2 = (srcy> desty) ? srcy : desty; // Establish selection rectangle origin. rectSelection.x = x1; rectSelection.y = y1; // Establish selection rectangle extents. rectSelection.width = (x2-x1)+1; rectSelection.height = (y2-y1)+1; // Draw selection rectangle. Graphics2D g2d = (Graphics2D) g; g2d.setStroke (bs); g2d.setPaint (gp); g2d.draw (rectSelection);}在選擇矩形繪制以前,它的左上和右下角必須對標示出來,用來確定矩形的原點和范圍。以至于你可以在不同的方向拖拽出選擇矩形(例如右下或者左上方向),srcx/destx和srcy/desty的最小值表示左上角,相似地,它們的最大值表示右下角。圖像修剪在選擇子圖像后,你想要修剪捕獲的圖像得到子圖像。圖像修剪啟動Crop中的菜單項的動作監聽器,它請求ImageArea將捕獲的圖像修剪為選擇的子圖像。若操作成果,監聽器則重置ImageArea的滾動條。反之,監聽器通過對話框給出一個“Out of bounds錯誤信息。// Crop ImageArea component and adjust the scrollbars if// cropping succeeds.if (ia.crop ()){ jsp.getHorizontalScrollBar ().setValue (0); jsp.getVerticalScrollBar ().setValue (0);}else showError ('Out of bounds.');因為修剪操作不重置Capture GUI的大小,所以可以同時看到主窗口的背景和結果圖像(初始修剪后的)。圖2顯示了選擇圖像的一部分時還可能選中背景的一部分。 圖 2. 嘗試選擇多于這個圖像主窗口的背景像素不是捕獲的圖像的一部分;就不可能把它們包含在修剪的圖片內。因此,無論何時把背景像素包含在修剪區域內,操作都會失敗,并且會給出一個“Out of bounds錯誤信息。修剪操作由ImageArea的public Boolean crop()方法處理。如果完成了修剪或者沒有選擇子圖像(當沒有選中內容時調用這個方法是非常方便的)該方法(如下所示)返回true。如果在選擇區域中包含了背景像素則返回false。public boolean crop (){ // There is nothing to crop if the selection rectangle is only a single // point. if (srcx == destx && srcy == desty) return true; // Assume success. boolean succeeded = true; // Compute upper-left and lower-right coordinates for selection rectangle // corners. int x1 = (srcx < destx) ? srcx : destx; int y1 = (srcy < desty) ? srcy : desty; int x2 = (srcx> destx) ? srcx : destx; int y2 = (srcy> desty) ? srcy : desty; // Compute width and height of selection rectangle. int width = (x2-x1)+1; int height = (y2-y1)+1; // Create a buffer to hold cropped image. BufferedImage biCrop = new BufferedImage (width, height, BufferedImage.TYPE_INT_RGB); Graphics2D g2d = biCrop.createGraphics (); // Perform the crop operation. try { BufferedImage bi = (BufferedImage) image; BufferedImage bi2 = bi.getSubimage (x1, y1, width, height); g2d.drawImage (bi2, null, 0, 0); } catch (RasterFormatException e) { succeeded = false; } g2d.dispose (); if (succeeded) setImage (biCrop); // Implicitly remove selection rectangle. else { // Prepare to remove selection rectangle. srcx = destx; srcy = desty; // Explicitly remove selection rectangle. repaint (); } return succeeded;}crop()方法調用BufferedImage的public BufferedImage getSubimage(int x, int y, int w, int h)方法摘取選擇區域內的子圖像。如果該方法的參數沒有指定BufferedImage內的圖像,它就會拋出一個java.awt.image.RasterFormatException,因此就會返回false。圖像保存Capture允許你把捕獲的圖像保存為一個jpeg文件。你通過一個保存文件選擇器指定文件名,選擇器由Capture類的構造函數創建:// Construct a save file-chooser. Initialize the starting directory to// the current directory, do not allow the user to select the 'all files'// filter, and restrict the files that can be selected to those ending// with .jpg or .jpeg extensions.final JFileChooser fcSave = new JFileChooser ();fcSave.setCurrentDirectory (new File (System.getProperty ('user.dir')));fcSave.setAcceptAllFileFilterUsed (false);fcSave.setFileFilter (new ImageFileFilter ());為了限制文件選擇器的選擇是文件夾或者是以.jpg或.jpeg為后綴的文件,就使用了ImageFileFilter類的一個實例作為保存時文件選擇器的文件過濾器。該方法對于任何非文件夾和后綴名非.jpg/.jpeg的文件都返回false:public boolean accept (File f){ // Allow the user to select directories so that the user can navigate the // file system. if (f.isDirectory ()) return true; // Allow the user to select files ending with a .jpg or a .jpeg // extension. String s = f.getName (); int i = s.lastIndexOf ('.'); if (i> 0 && i < s.length ()-1) { String ext = s.substring (i+1).toLowerCase (); if (ext.equals ('jpg') || ext.equals ('jpeg')) return true; } // Nothing else can be selected. return false;}當你選擇了Save As…菜單項時,它的監聽器就會顯示一個保存文件選擇器。假定你沒有退出選擇器,監聽器就會確保你選擇的文件名是以.jpg或.jpeg為后綴名。繼續,監聽器會確定文件是否存在,這樣你就不會無意中覆蓋一個存在的文件。// Present the 'save' file-chooser without any file selected.// If the user cancels this file-chooser, exit this method.fcSave.setSelectedFile (null);if (fcSave.showSaveDialog (Capture.this) != JFileChooser.APPROVE_OPTION) return;// Obtain the selected file. Validate its extension, which // must be .jpg or .jpeg. If extension not present, append// .jpg extension.File file = fcSave.getSelectedFile ();String path = file.getAbsolutePath ().toLowerCase ();if (!path.endsWith ('.jpg') && !path.endsWith ('.jpeg')) file = new File (path += '.jpg');// If the file exists, inform the user, who might not want// to accidentally overwrite an existing file. Exit method// if the user specifies that it is not okay to overwrite// the file. if (file.exists ()){ int choice = JOptionPane. showConfirmDialog (null,'Overwrite file?','Capture',JOptionPane.YES_NO_OPTION); if (choice == JOptionPane.NO_OPTION) return;}如果文件不存在或者你允許覆蓋已經存在的文件,監聽器就會將捕獲的內容保存為一個選擇的文件。為了完成這個任務,監聽器使用Java的ImageIO框架選擇一個jpeg writer,指定文件作為writer的目標,設置writer的壓縮品質為95%,然后把圖像寫入到文件中。ImageWriter writer = null;ImageOutputStream ios = null;try{ // Obtain a writer based on the jpeg format. Iterator iter; iter = ImageIO.getImageWritersByFormatName ('jpeg'); // Validate existence of writer. if (!iter.hasNext ()) { showError ('Unable to save image to jpeg file type.'); return; } // Extract writer. writer = (ImageWriter) iter.next(); // Configure writer output destination. ios = ImageIO.createImageOutputStream (file); writer.setOutput (ios); // Set jpeg compression quality to 95%. ImageWriteParam iwp = writer.getDefaultWriteParam (); iwp.setCompressionMode (ImageWriteParam.MODE_EXPLICIT); iwp.setCompressionQuality (0.95f); // Write the image. writer.write (null, new IIOImage ((BufferedImage)ia.getImage (), null, null), iwp);}catch (IOException e2){ showError (e2.getMessage ());}finally{ try { // Cleanup. if (ios != null) { ios.flush (); ios.close (); } if (writer != null) writer.dispose (); } catch (IOException e2) { }}讓代碼自己清理一直是一個不錯的主意。我把ImageIO的清理代碼放在了finally子句中,以至于無論是正常結束還是拋出異常,它都可以執行。總結Capture限制了捕獲的內容只能在主屏幕設備內。你可能想增強Capture來捕獲所有附加屏幕設備(或許是一個巨大的虛擬屏幕)的內容。增強之一,你需要包含下面的代碼,它捕獲所有屏幕的內容,將它和Capture.java已經存在的代碼集成。GraphicsEnvironment graphenv = GraphicsEnvironment.getLocalGraphicsEnvironment ();GraphicsDevice [] screens = graphenv.getScreenDevices ();BufferedImage [] captures = new BufferedImage [screens.length];for (int i = 0; i < screens.length; i++){ DisplayMode mode = screens [i].getDisplayMode (); Rectangle bounds = new Rectangle (0, 0, mode.getWidth (), mode.getHeight ()); captures [i] = new Robot (screens [i]).createScreenCapture (bounds);}把以上代碼放到Capture菜單項的動作監聽器內。然后先引入代碼創建一個bigScreen要引用的足夠大的BufferedImage,它可以保存被captures數組引用的所有BufferedImage內容;接著引入代碼把它們的繪制到bigScreen中。Capture現在成為了多屏幕捕獲器就好像是一個單屏幕捕獲器。關于作者Jeff Friesen是一個自由軟件開發者和教育家,特別是在C、C++和Java技術領域。資源Matrix中文Java社區:http://www.matrix.org.cn下載文中的代碼文件:http://www.javaworld.com/javaworld/jw-04-2006/games/jw-0424-funandgames.zip你可以使用在線開發工具DevSquare編譯和運行Java Fun And Games中提供的Applet。工具入門請閱讀這篇用戶向導:http://www.javaworld.com/javaworld/jw-12-2005/jw-devsquare.htmlDevSquare:http://www.devsquare.com/index.html Java, java, J2SE, j2se, J2EE, j2ee, J2ME, j2me, ejb, ejb3, JBOSS, jboss, spring, hibernate, jdo, struts, webwork, ajax, AJAX, mysql, MySQL, Oracle, Weblogic, Websphere, scjp, scjd 摘要Java Fun and Games(Java娛樂和游戲)提供了通過Java的Robot類捕獲主屏幕設備的功能,并且可以將整個屏幕或者選定的一部分保存為jpeg文件。注意:現在你可以使用在線開發工具DevSquare編譯和運行Java Fun and Games中提供的applet。DevSquare入門請閱
標簽: Java
相關文章:
主站蜘蛛池模板: 999色综合| 国产欧美另类久久久品 | 国产v精品成人免费视频400条 | 国产情侣草莓视频在线 | 中文字幕在线综合 | 亚州成人| 欧美精品一区在线看 | 亚洲国产精品人久久电影 | 欧美亚洲视频 | 色青青草原桃花久久综合 | 妞干网在线免费视频 | 亚洲六月丁香色婷婷综合久久 | 欧美日韩精品一区二区三区 | 黄色毛片在线 | 欧美一区二区三区男同 | 91热这里只有精品 | 精品在线免费观看 | 在线看黄网 | 久久久日韩精品国产成人 | fc2成年免费共享视频网站 | 亚洲欧美偷拍视频 | 国产99视频精品免视看7 | 亚洲欧美久久精品 | 亚洲第一综合网 | 一级做性色a爱片久久片 | 日本黄色大片免费 | 亚洲 欧美 清纯 校园 另类 | 国产视频在线一区 | 国产日韩亚洲欧洲一区二区三区 | 欧美色噜噜| 亚洲国产成人在线观看 | 黄色小视频在线观看免费 | 看黄免费在线 | 国产精品日本一区二区在线播放 | 免看黄| 午夜视频免费 成人 | 成人永久福利免费观看 | 日韩黄色大片 | 亚洲欧美一区二区三区 | 精品一区二区久久久久久久网精 | 永久免费在线观看视频 |