代码之家  ›  专栏  ›  技术社区  ›  parsecer

硒:java.awt.image.RasterFormatException:(y+height)在使用元素大小和位置时在光栅之外

  •  0
  • parsecer  · 技术社区  · 7 年前

    我有一个密码 this

     class SshotofElement {
    
        public static void screenShotElement() throws InterruptedException,IOException {
            System.setProperty("webdriver.chrome.driver", "chromedriver.exe");
    
            DesiredCapabilities capabilities = DesiredCapabilities.chrome();
            capabilities.setCapability("marionette", true);
            WebDriver driver = new ChromeDriver(capabilities);
    
            driver.get("http://learn-selenium-easy.blogspot.com/");
            driver.manage().window().maximize();
    
            // Xpath of element to take screen shot
            WebElement element=driver.findElement(By.xpath("//*[@id='PopularPosts1']"));
            System.out.println(element.getSize());
            File screenshot = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
    
            // Take full screen screenshot
            BufferedImage  fullImg = ImageIO.read(screenshot);
            Point point = element.getLocation();
            int elementWidth = element.getSize().getWidth();
            int elementHeight = element.getSize().getHeight();
            BufferedImage elementScreenshot= fullImg.getSubimage(point.getX(), point.getY(), elementWidth,elementHeight);  //exception here
    
            // crop the image to required
            ImageIO.write(elementScreenshot, "png", screenshot);
            FileUtils.copyFile(screenshot, new File("mostread_screenshot.png"));//path to save screen shot
    
            driver.close();
        }
    }
    

    我得到了 java.awt.image.RasterFormatException: (y + height) is outside of Raster 例外,但在线 BufferedImage elementScreenshot= fullImg.getSubimage(point.getX(), point.getY(), elementWidth,elementHeight);

    0 回复  |  直到 7 年前
        1
  •  2
  •   Amit Jain    7 年前
    1. 您要裁剪的元素图像不在代码所拍摄的屏幕截图中。若您把调试和打印全屏快照路径并手动查看它,则可以看到要从图像中裁剪的所需元素不在其中。

    2. 滚动页面 带来 进入之内

    3. 也, Point

    4. 其次,如果我们看到下面的值

      ImageIO.read(screenshot).getHeight() // ~ 943 => Total height
      element.getSize().getHeight() // ~ 511 => Element height 
      point.getY() // ~ 743 => start top side y coordinate of element
      
    5. 失去了原始屏幕截图坐标。

    所以我们需要在传递坐标的同时进行一些调整。

    @Test
    public void subImageTest() throws InterruptedException, IOException {
        driver.get("http://learn-selenium-easy.blogspot.com/");
        ((JavascriptExecutor)driver).executeScript("window.scrollBy(0,600)");
       File screenshot = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
    
        WebElement element=driver.findElement(By.xpath("//*[@id='PopularPosts1']"));
        System.out.println(element.getSize());
    
      // Take full screen screenshot
        BufferedImage  fullImg = ImageIO.read(screenshot);
        ImageIO.read(screenshot).getHeight()
        System.out.println(fullImg.getHeight()); 
        System.out.println(fullImg.getWidth());
    
        Point point = element.getLocation();
        int elementWidth = element.getSize().getWidth(); 
        int elementHeight = element.getSize().getHeight();
    
        // Now no exception here
        BufferedImage elementScreenshot= fullImg.getSubimage(220, 170,elementWidth+150,elementHeight+100);
    
        // crop the image to required
        ImageIO.write(elementScreenshot, "png", screenshot);
        FileUtils.copyFile(screenshot, new File("C:\\Users\\AppData\\Local\\Temp\\mostread_screenshot.png"));//path to save screen shot
    
    }
    

    程序执行后元素的最终子图像 enter image description here

        2
  •  1
  •   undetected Selenium    7 年前

    Java文档 RasterFormatException 中存在无效布局信息时引发 Raster .


    获取位置()

    硒文档 getLocation() 左上角 元素的。


    getSubimage()

    getSubimage() 返回由指定矩形区域定义的子图像。返回的BufferedImage与原始映像共享相同的数据数组,定义如下:

    getSubimage
    public BufferedImage getSubimage(int x,
                     int y,
                     int w,
                     int h)
    Returns a subimage defined by a specified rectangular region. The returned BufferedImage shares the same data array as the original image.
    
    Parameters: 
        x - the X coordinate of the upper-left corner of the specified rectangular region 
        y - the Y coordinate of the upper-left corner of the specified rectangular region 
        w - the width of the specified rectangular region 
        h - the height of the specified rectangular region 
    
    Returns: 
        a BufferedImage that is the subimage of this BufferedImage. 
    
    Throws: 
        RasterFormatException - if the specified area is not contained within this BufferedImage. 
    

    System.out.println() 线来展示到底出了什么问题。

    • 代码块:

      public class A_demo 
      {
          public static void main(String[] args) throws Exception 
          {
                  System.setProperty("webdriver.chrome.driver", "C:\\Utility\\BrowserDrivers\\chromedriver.exe");
                  ChromeOptions options = new ChromeOptions();
                  options.addArguments("start-maximized");
                  options.addArguments("disable-infobars");
                  WebDriver driver = new ChromeDriver(options);
                  driver.get("http://learn-selenium-easy.blogspot.com/");
                  // Xpath of element to take screen shot
                  WebElement element=driver.findElement(By.xpath("//*[@id='PopularPosts1']"));
                  System.out.println("Element size is:"+element.getSize());
                  File screenshot = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
                  FileUtils.copyFile(screenshot, new File("./Screenshots/mostread_TakesScreenshot.png")); //path to save screen shot
      
                  // Take full screen screenshot
                  BufferedImage  fullImg = ImageIO.read(screenshot);
                  Point point = element.getLocation();
                  System.out.println("Co-ordinates where on the page is the top left-hand corner of the rendered element:"+point);
                  int elementWidth = element.getSize().getWidth();
                  System.out.println("Element width is:"+elementWidth);
                  int elementHeight = element.getSize().getHeight();
                  System.out.println("Element height is:"+elementHeight);
                  BufferedImage elementScreenshot= fullImg.getSubimage(point.getX(), point.getY(), elementWidth,elementHeight);  //exception here
      
                  // crop the image to required
                  ImageIO.write(elementScreenshot, "png", screenshot);
                  FileUtils.copyFile(screenshot, new File("./Screenshots/mostread_BufferedImage.png"));//path to save screen shot
          }    
      }
      
    • 控制台输出:

      INFO: Detected dialect: W3C
      Element size is:(340, 486)
      Co-ordinates where on the page is the top left-hand corner of the rendered element:(104, 744)
      Element width is:340
      Element height is:486
      Exception in thread "main" java.awt.image.RasterFormatException: (y + height) is outside of Raster
          at sun.awt.image.ByteInterleavedRaster.createWritableChild(Unknown Source)
          at java.awt.image.BufferedImage.getSubimage(Unknown Source)
          at demo.A_demo.main(A_demo.java:78)
      

    如前所述,根据您的代码块 fullImg.getSubimage() 将尝试返回 BufferedImage 元素截图 它将是由指定的矩形区域定义的子图像:

    • point.getX() - 104
    • point.getY() -
    • w: 指定矩形区域的宽度-elementWidth- 340
    • 486

    所以,预期的高度 缓冲图像 744 486 = 1230 光栅 . 因此您看到了错误。


    解决方案

    使用 你可以使用 AShot() ashot-1.4.4.jar , ChromeDriver v2.41版 铬v 68.0

    注意 阿肖特() 方法来自 ashot-1.4.4.jar jQuery 启用 Web应用程序

    • 代码块:

      import ru.yandex.qatools.ashot.AShot;
      import ru.yandex.qatools.ashot.Screenshot;
      
      public class A_demo 
      {
          public static void main(String[] args) throws Exception 
          {
              System.setProperty("webdriver.chrome.driver", "C:\\Utility\\BrowserDrivers\\chromedriver.exe");
              ChromeOptions options = new ChromeOptions();
              options.addArguments("start-maximized");
              options.addArguments("disable-infobars");
              WebDriver driver = new ChromeDriver(options);
              driver.get("http://learn-selenium-easy.blogspot.com/");
              WebElement myWebElement = new WebDriverWait(driver, 20).until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//div[@id='PopularPosts1']")));
              ((JavascriptExecutor)driver).executeScript("arguments[0].scrollIntoView();", myWebElement);
              Screenshot myScreenshot = new AShot().takeScreenshot(driver, myWebElement);
              ImageIO.write(myScreenshot.getImage(),"PNG",new File("./Screenshots/elementAShotScreenshot.png"));
              driver.quit();
          }    
      }
      

    您可以在以下位置找到一些相关讨论:


    奥特罗

    你可以找到关于 How to take screenshot with Selenium WebDriver