为了账号安全,请及时绑定邮箱和手机立即绑定

Selenium:java.awt.image.RasterFormatException:

Selenium:java.awt.image.RasterFormatException:

隔江千里 2023-03-09 11:21:58
我有从本教程中获取的代码。它会转到 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);。我不确定为什么会这样,因为图像的点和大小是从元素本身获取的。
查看完整描述

2 回答

?
江户川乱折腾

TA贡献1851条经验 获得超5个赞

  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

所以我相信当从 x,y 绘制高度为 743 的矩形时,它超出了原始屏幕截图坐标。


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


@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


}

程序执行后元素的最终子图像 

//img1.sycdn.imooc.com//640951230001c3cd04770603.jpg

查看完整回答
反对 回复 2023-03-09
?
一只名叫tom的猫

TA贡献1906条经验 获得超3个赞

RasterFormat异常

根据Java Docs,如果 Raster中存在无效的布局信息,则会抛出RasterFormatException


获取位置()

根据Selenium 文档 返回包含元素左上角getLocation()位置的点。


获取子图像()

根据Java Docs 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()将尝试返回一个BufferedImageie elementScreenshot,这将是一个由矩形区域指定的子图像:

  • x:指定矩形区域左上角的X坐标 - point.getX()104

  • y:指定矩形区域左上角的Y坐标 - point.getY()744

  • w:指定矩形区域的宽度 - elementWidth - 340

  • h:指定矩形区域的高度 - elementHeight - 486

因此,预期的高度BufferedImage变成了7444861230,这几乎超出了Raster 的范围。因此您会看到错误。


解决方案

要截取特定元素或特定 div 使用爪哇您可以在使用Selenium Java Client v3.14.0ChromeDriver v2.41Chrome 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();

    }    

}


查看完整回答
反对 回复 2023-03-09
  • 2 回答
  • 0 关注
  • 112 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信