Java(机器人)截图超出可见范围

时间:2012-08-12 02:07:16

标签: java screenshot awtrobot

我想在一个比我的屏幕更大的整个网站上一次拍摄一个屏幕截图。我知道如何使用Robot类来截取可见区域的截图。我认为这样做的一种方法是:

  1. 启动浏览器,转到所需的网站
  2. 开始我的计划
  3. 程序将截取可见区域的截图
  4. 程序将向下滚动以使页面的后半部分可见并截取屏幕截图
  5. 两个截图将合并
  6. 这有点笨拙的解决方案,此时我甚至不确定是否可能(滚动浏览器的窗口)。所以我正在寻找更好的解决方案的提示。

    编辑1:这是我在原帖中所设想的。流程是(原型):

    1. 打开浏览器,转到显示器1中的所需网站
    2. 在监视器2中,运行程序(在我的例子中来自Net beans)
    3. 程序捕获第一个屏幕截图,但是如果调用Robot.mouseScroll,则它是不滚动webrowser的Ne​​tBeans窗口
    4. 要滚动浏览器屏幕,我移动鼠标Monitor 1,单击它以获得焦点,滚动然后再拍摄另一个屏幕截图。现在我有两个可以拼接的png图像。
    5. 问题是,虽然我在技术上可以做到这一点,但我不能同时在我的计算机上做任何其他事情,因为我正在通过程序移动我的鼠标。我的目标是让我的程序截取屏幕并同时分析图像(拼接和提取信息),同时我在Excel中工作。按照目前的设置,这是不可能的。

      此外,它开始看起来Java根本无法做到这一点。有趣的是,JavaScript可能能够并且看起来像使用Win Api的C ++将能够如此。这是一种耻辱。任何一个人?

      /** * @param args the command line arguments */ public static void main(String[] args) throws IOException { int width; int height;

          try{
              // Get screen devices.
              GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
              GraphicsDevice[] gdevices = ge.getScreenDevices();
      
              // Find out widht and height of each, print line.
              for (int i = 0; i < gdevices.length; i++){
                  System.out.println("Device " + i);
                  System.out.println("Width:" + gdevices[i].getDisplayMode().getWidth());
                  System.out.println("Height:" + gdevices[i].getDisplayMode().getHeight());
              }
      
              // Get width and height again for later. Don't worry about this now.
              width = gdevices[1].getDisplayMode().getWidth();
              height = gdevices[1].getDisplayMode().getHeight();
      
              // Initiate robot.
              Robot robot = new Robot(gdevices[1]);
              // Size of printscreen area. Temporary. Will be entire screen later.
              Rectangle captureSize = new Rectangle(0,0,500,500);
      
              // Take screenshot on gdevice[1]
              BufferedImage bufferedImage = robot.createScreenCapture(captureSize);
              File outputfile = new File("My Screenshot" + 1 + ".png");
              boolean write = ImageIO.write(bufferedImage, "png",outputfile);
      
              // Preparing to take another screenshot after.
              /* Need to move mouse to monitor where screenshot is taken. Mouse
               * is currently at a monitor that displays NetBeans, which is where 
               * I'm running this from, for now.
               */
      
              robot.mouseMove(200,200);
              /* Need to activate window by gaining focus, don't how to do with robot
               * do with mouse instead.
               */
              robot.mousePress(InputEvent.BUTTON1_MASK);
              robot.mouseRelease(InputEvent.BUTTON1_MASK);
              /* After the first screen shot, scroll screen that's now 
               * active (focused?)
               */
              robot.mouseWheel(3);
      
              // Take second screenshot.
              robot.delay(1000);
              bufferedImage = robot.createScreenCapture(captureSize);
              outputfile = new File("My Screenshot" + 2 + ".png");
              //write into second half
              write = ImageIO.write(bufferedImage, "png",outputfile);
          }
          catch (AWTException e){
              System.err.println("Somethingfishy is going on ...");
          }
      }
      

      try{ // Get screen devices. GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); GraphicsDevice[] gdevices = ge.getScreenDevices(); // Find out widht and height of each, print line. for (int i = 0; i < gdevices.length; i++){ System.out.println("Device " + i); System.out.println("Width:" + gdevices[i].getDisplayMode().getWidth()); System.out.println("Height:" + gdevices[i].getDisplayMode().getHeight()); } // Get width and height again for later. Don't worry about this now. width = gdevices[1].getDisplayMode().getWidth(); height = gdevices[1].getDisplayMode().getHeight(); // Initiate robot. Robot robot = new Robot(gdevices[1]); // Size of printscreen area. Temporary. Will be entire screen later. Rectangle captureSize = new Rectangle(0,0,500,500); // Take screenshot on gdevice[1] BufferedImage bufferedImage = robot.createScreenCapture(captureSize); File outputfile = new File("My Screenshot" + 1 + ".png"); boolean write = ImageIO.write(bufferedImage, "png",outputfile); // Preparing to take another screenshot after. /* Need to move mouse to monitor where screenshot is taken. Mouse * is currently at a monitor that displays NetBeans, which is where * I'm running this from, for now. */ robot.mouseMove(200,200); /* Need to activate window by gaining focus, don't how to do with robot * do with mouse instead. */ robot.mousePress(InputEvent.BUTTON1_MASK); robot.mouseRelease(InputEvent.BUTTON1_MASK); /* After the first screen shot, scroll screen that's now * active (focused?) */ robot.mouseWheel(3); // Take second screenshot. robot.delay(1000); bufferedImage = robot.createScreenCapture(captureSize); outputfile = new File("My Screenshot" + 2 + ".png"); //write into second half write = ImageIO.write(bufferedImage, "png",outputfile); } catch (AWTException e){ System.err.println("Somethingfishy is going on ..."); } }

      编辑2:新方法 好吧,想一想,即使我弄清楚焦点的事情(例如使用alt + tab而不是移动)也没有用,因为我需要同时在excel中工作。我将开始另一个关于“虚拟监视器”想法的问题。感谢您提供的想法。

4 个答案:

答案 0 :(得分:1)

页面是否会以JEditorPane呈现?如果是,请参阅ComponentImageCapture课程。

答案 1 :(得分:0)

机器人类可以完全按照您的概述使用,只需确保在单击滚动和第二个屏幕截图之间包含延迟。这是Robot的一个很好的应用。你应该在这里发布你的代码。  我认为没有办法屏幕捕捉屏幕上没有的东西。您受视频卡和显示分辨率的限制。

答案 2 :(得分:0)

请参阅我在问题中编辑的内容。程序流程必须重定向到虚拟监视器或类似的东西。感谢。

答案 3 :(得分:0)

尝试

      Dimension size = driver.manage().window().getSize();
      Point point = driver.manage().window().getPosition();
      Robot robot = new Robot();
      String format = "png";
      File tempFile = new File(System.getProperty("user.dir") + "//" + screenshotFolder + "//" + fileName);
      Rectangle captureRect = new Rectangle(point.getX(), point.getY(), size.getWidth(), size.getHeight());
      BufferedImage captureImage = robot.createScreenCapture(captureRect);
      ImageIO.write(captureImage, format, tempFile);