成人在线亚洲_国产日韩视频一区二区三区_久久久国产精品_99国内精品久久久久久久

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

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

瀏覽:181日期: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
相關文章:
成人在线亚洲_国产日韩视频一区二区三区_久久久国产精品_99国内精品久久久久久久
亚洲成人一区在线| 欧美成人a∨高清免费观看| 在线视频中文字幕一区二区| 亚洲三级小视频| 欧美日韩福利| 2023国产精品| 成人av集中营| 精品第一国产综合精品aⅴ| 国产精品888| 日韩一区二区视频| 国产一区二区三区日韩 | 日本高清不卡aⅴ免费网站| 一区av在线播放| 午夜国产精品视频| 国产欧美一区二区三区在线老狼| 99久久99久久精品国产片果冻| 日韩一区二区三区四区| 国产一区二区精品在线观看| 欧美日韩色一区| 麻豆成人综合网| 欧美在线一区二区三区| 免费看日韩a级影片| 久久视频一区| 日本欧美韩国一区三区| 久久日韩精品| 三级久久三级久久| 久久精品99| 日韩高清不卡在线| 日本二三区不卡| 久久99最新地址| 91精品国产91久久久久久一区二区| 国产又黄又大久久| 在线播放国产精品二区一二区四区 | 国产成人在线观看| 日韩一区二区三区四区 | 9久草视频在线视频精品| 久久综合久久鬼色中文字| 成人高清视频在线| 日韩精品在线网站| 成人av动漫在线| 国产色综合久久| 极品av少妇一区二区| 亚洲欧美综合另类在线卡通| 韩日午夜在线资源一区二区| 亚洲摸摸操操av| 亚洲一区中文| 美女看a上一区| 91精品一区二区三区在线观看| 99免费精品视频| 日本一区二区三区四区在线视频| 欧美另类视频| 亚洲激情在线播放| 久久久一二三| 国产在线精品一区二区夜色| 91精品国产91久久久久久最新毛片| zzijzzij亚洲日本少妇熟睡| 国产欧美日韩另类一区| 日韩一级精品| 免费不卡在线视频| 555www色欧美视频| 国产69精品久久99不卡| 一区二区三区精品在线| 伊人开心综合网| 一区二区三区国产精品| 亚洲精品国产一区二区精华液 | 久久久99精品久久| 日韩av电影免费观看高清完整版 | 成人开心网精品视频| 欧美激情一区二区三区| 一区二区高清视频| 天天色 色综合| 日韩女优av电影| 黄色免费成人| 男女男精品视频网| 久久精品一区八戒影视| 一区二区三区你懂的| 另类小说综合欧美亚洲| 精品国产乱码久久久久久牛牛| 在线欧美亚洲| 蜜桃视频在线观看一区二区| 精品乱码亚洲一区二区不卡| 在线看无码的免费网站| 蜜臀av性久久久久蜜臀aⅴ| 日韩视频永久免费| 国产在线欧美日韩| 亚洲成av人**亚洲成av**| 91精品国产欧美一区二区成人| 国产精品igao视频网网址不卡日韩| 亚洲一本大道在线| 欧美大片在线观看一区| 国产日韩欧美三区| 国产精品一区二区x88av| 中文字幕一区二区三区色视频| 久久在线视频| 99国内精品久久| 韩日av一区二区| 综合久久一区二区三区| 欧美精品久久99| 亚洲激情另类| 成人一区二区视频| 亚洲精品va在线观看| 91精品在线免费| 国产日韩综合| av一区二区三区| 三级一区在线视频先锋 | 久久日韩精品一区二区五区| 亚洲一区二区三区高清| av网站一区二区三区| 亚洲第一会所有码转帖| 精品日本一线二线三线不卡| 91麻豆精品在线观看| 欧美三区在线| 精品一区二区三区在线观看| 国产在线观看一区二区| 国产欧美一区二区精品性色超碰| 久久综合狠狠| 欧美一区综合| 国产麻豆视频一区二区| 夜夜精品视频一区二区 | 亚洲第一福利一区| 国产亚洲婷婷免费| 欧美日韩国产经典色站一区二区三区 | 欧美精品tushy高清| 99re66热这里只有精品4| 国产黑丝在线一区二区三区| 亚洲国产成人av好男人在线观看| 国产欧美一区二区精品性色超碰| 欧美伦理视频网站| 美女久久网站| 伊人久久成人| av亚洲精华国产精华精华| 久久国产人妖系列| 亚洲一区二区不卡免费| 国产欧美一区二区精品婷婷 | 亚洲v中文字幕| 日本一区二区三区久久久久久久久不| 在线观看视频一区| 亚洲欧美日韩精品综合在线观看| 女女同性精品视频| 国产成a人亚洲| 蜜臀av一区二区在线观看 | 蜜臀久久99精品久久久久宅男 | 国模 一区 二区 三区| 成人福利视频网站| 国内精品在线播放| 偷拍与自拍一区| 亚洲猫色日本管| 国产精品久久久久永久免费观看 | 制服丝袜亚洲播放| 在线亚洲人成电影网站色www| 一本综合精品| 国产一区二区中文| av在线综合网| 国产成人在线观看免费网站| 激情五月婷婷综合| 美脚の诱脚舐め脚责91| 午夜久久久久久久久| 亚洲精品视频免费观看| 国产精品国产三级国产普通话99 | 欧美三级一区二区| 久久久久久九九九九| 99热这里只有成人精品国产| 激情另类综合| 黄色精品网站| 亚洲电影成人| 亚洲精品一区二区三区蜜桃久 | 欧美日韩精品电影| 欧美在线播放高清精品| 美女被久久久| 午夜在线视频一区二区区别 | 岛国精品在线观看| 欧美国产视频在线| 亚洲综合激情| 国产欧美日本在线| 国产三级精品在线不卡| 99视频日韩| 中文一区在线| 亚洲欧美综合| 欧美日韩在线一二三| 欧美在线高清| 国产精品hd| 亚洲国产一区在线| 99热精品在线| 午夜亚洲精品| 一区二区三区国产盗摄 | 国产美女av一区二区三区| 精品午夜一区二区三区在线观看| 国产在线精品一区二区不卡了 | 国产一区免费视频| 一区二区视频在线观看| av成人免费观看| 午夜亚洲视频| 欧美中文字幕一区二区三区亚洲| 91成人国产精品| 欧美日韩免费观看一区二区三区| 欧美精品一二三区| 欧美一区二区三区免费视频| 日韩视频国产视频| 国产午夜久久久久| 自拍偷在线精品自拍偷无码专区|