Selenium:java.awt.image.RasterFormatException:

我有从本教程中获取的代码。它会转到 learn-selenium-easy.blogspot.com 网站,寻找最常阅读/热门帖子部分并为其拍照:


 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);。我不确定为什么会这样,因为图像的点和大小是从元素本身获取的。


隔江千里
浏览 113回答 2
2回答

江户川乱折腾

您正在裁剪的元素图像不存在于代码截取的屏幕截图中。如果您放置调试并打印全屏截图路径并手动查看它,那么您可以看到要从图像中裁剪的所需元素不存在于其中。因此,首先我们需要滚动页面以将所需元素带入视图,然后截取屏幕截图。然后我们需要根据元素的位置裁剪图像。此外,Point类在给出元素的确切位置方面不是很可靠。其次,如果我们看到以下值ImageIO.read(screenshot).getHeight() // ~ 943 => Total heightelement.getSize().getHeight() // ~ 511 => Element height point.getY() // ~ 743 => start top side y coordinate of element所以我相信当从 x,y 绘制高度为 743 的矩形时,它超出了原始屏幕截图坐标。所以我们需要在传递坐标的同时进行一些调整。@Testpublic 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}程序执行后元素的最终子图像 

一只名叫tom的猫

RasterFormat异常根据Java Docs,如果 Raster中存在无效的布局信息,则会抛出RasterFormatException。获取位置()根据Selenium 文档 返回包含元素左上角getLocation()位置的点。获取子图像()根据Java Docs getSubimage()返回由指定矩形区域定义的子图像。返回的 BufferedImage 与原始图像共享相同的数据数组,定义为:getSubimagepublic 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: W3CElement 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:340Element height is:486Exception 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()将尝试返回一个BufferedImageie elementScreenshot,这将是一个由矩形区域指定的子图像:x:指定矩形区域左上角的X坐标 - point.getX()- 104y:指定矩形区域左上角的Y坐标 - point.getY()- 744w:指定矩形区域的宽度 - elementWidth - 340h:指定矩形区域的高度 - elementHeight - 486因此,预期的高度BufferedImage变成了744+ 486= 1230,这几乎超出了Raster 的范围。因此您会看到错误。解决方案要截取特定元素或特定 div 使用硒和爪哇您可以在使用Selenium Java Client v3.14.0、ChromeDriver v2.41、Chrome v 68.0AShot()时使用导入ashot-1.4.4.jar的方法。注意:来自ashot-1.4.4.jar 的AShot()方法仅适用于启用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();    }    }
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java