电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

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

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

瀏覽:119日期: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
相關文章:
主站蜘蛛池模板: DAIKIN电磁阀-意大利ATOS电磁阀-上海乾拓贸易有限公司 | 拉伸膜,PE缠绕膜,打包带,封箱胶带,包装膜厂家-东莞宏展包装 | 南京种植牙医院【官方挂号】_南京治疗种植牙医院那个好_南京看种植牙哪里好_南京茀莱堡口腔医院 尼龙PA610树脂,尼龙PA612树脂,尼龙PA1010树脂,透明尼龙-谷骐科技【官网】 | 不锈钢管件(不锈钢弯头,不锈钢三通,不锈钢大小头),不锈钢法兰「厂家」-浙江志通管阀 | 深圳激光打标机_激光打标机_激光焊接机_激光切割机_同体激光打标机-深圳市创想激光科技有限公司 深圳快餐店设计-餐饮设计公司-餐饮空间品牌全案设计-深圳市勤蜂装饰工程 | 免费个人pos机申请办理-移动pos机刷卡-聚合收款码办理 | 钢格栅板_钢格板网_格栅板-做专业的热镀锌钢格栅板厂家-安平县迎瑞丝网制造有限公司 | 煤矿人员精确定位系统_矿用无线通信系统_煤矿广播系统 | YAGEO国巨电容|贴片电阻|电容价格|三星代理商-深圳市巨优电子有限公司 | 汝成内控-行政事业单位内部控制管理服务商 | 吹田功率计-长创耐压测试仪-深圳市新朗普电子科技有限公司 | 上海皓越真空设备有限公司官网-真空炉-真空热压烧结炉-sps放电等离子烧结炉 | 编织人生 - 权威手工编织网站,编织爱好者学习毛衣编织的门户网站,织毛衣就上编织人生网-编织人生 | 全自动包装秤_全自动上袋机_全自动套袋机_高位码垛机_全自动包装码垛系统生产线-三维汉界机器(山东)股份有限公司 | 皮带式输送机械|链板式输送机|不锈钢输送机|网带输送机械设备——青岛鸿儒机械有限公司 | 网站建设-高端品牌网站设计制作一站式定制_杭州APP/微信小程序开发运营-鼎易科技 | 泥沙分离_泥沙分离设备_泥砂分离机_洛阳隆中重工机械有限公司 | 针焰试验仪,灼热丝试验仪,漏电起痕试验仪,水平垂直燃烧试验仪 - 苏州亚诺天下仪器有限公司 | 写方案网_方案策划方案模板下载| 软文发布-新闻发布推广平台-代写文章-网络广告营销-自助发稿公司媒介星 | 东莞市海宝机械有限公司-不锈钢分选机-硅胶橡胶-生活垃圾-涡电流-静电-金属-矿石分选机 | 河南正规膏药生产厂家-膏药贴牌-膏药代加工-修康药业集团官网 | 深圳诚暄fpc首页-柔性线路板,fpc柔性线路板打样生产厂家 | 昆山新莱洁净应用材料股份有限公司-卫生级蝶阀,无菌取样阀,不锈钢隔膜阀,换向阀,离心泵 | 圆形振动筛_圆筛_旋振筛_三次元振动筛-河南新乡德诚生产厂家 | 江西自考网-江西自学考试网| 蜗轮丝杆升降机-螺旋升降机-丝杠升降机厂家-润驰传动 | 青岛侦探_青岛侦探事务所_青岛劝退小三_青岛调查出轨取证公司_青岛婚外情取证-青岛探真调查事务所 | 硅胶管挤出机厂家_硅胶挤出机生产线_硅胶条挤出机_臣泽智能装备 贵州科比特-防雷公司厂家提供贵州防雷工程,防雷检测,防雷接地,防雷设备价格,防雷产品报价服务-贵州防雷检测公司 | 干粉砂浆设备-干粉砂浆生产线-干混-石膏-保温砂浆设备生产线-腻子粉设备厂家-国恒机械 | 手持气象站_便携式气象站_农业气象站_负氧离子监测站-山东万象环境 | 丹佛斯变频器-丹佛斯压力开关-变送器-广州市风华机电设备有限公司 | 有福网(yofus.com)洗照片冲印,毕业聚会纪念册相册制作个性DIY平台 | 作文导航网_作文之家_满分作文_优秀作文_作文大全_作文素材_最新作文分享发布平台 | YT保温材料_YT无机保温砂浆_外墙保温材料_南阳银通节能建材高新技术开发有限公司 | 成都离婚律师|成都结婚律师|成都离婚财产分割律师|成都律师-成都离婚律师网 | 厂房出租-厂房规划-食品技术-厂房设计-厂房装修-建筑施工-设备供应-设备求购-龙爪豆食品行业平台 | 武汉画册印刷厂家-企业画册印刷-画册设计印刷制作-宣传画册印刷公司 - 武汉泽雅印刷厂 | 除湿机|工业除湿机|抽湿器|大型地下室车间仓库吊顶防爆除湿机|抽湿烘干房|新风除湿机|调温/降温除湿机|恒温恒湿机|加湿机-杭州川田电器有限公司 | 绿叶|绿叶投资|健康产业_绿叶投资集团有限公司 | 包塑丝_高铁绑丝_地暖绑丝_涂塑丝_塑料皮铁丝_河北创筹金属丝网制品有限公司 |