RasterFormatException
As per the Java Docs RasterFormatException is thrown if there is invalid layout information in the Raster.
getLocation()
As per the Selenium Documentation getLocation()
returns the point containing the location of the top left-hand corner of the element.
getSubimage()
As per the Java Docs getSubimage()
returns a subimage defined by a specified rectangular region. The returned BufferedImage shares the same data array as the original image and is defined as:
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.
I have taken your own code, added a couple of System.out.println()
lines to showcase what exactly going wrong.
Code Block:
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
}
}
Console Output:
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)
Explanation
As discussed earlier, as per your code block fullImg.getSubimage()
will try to return a BufferedImage
i.e. elementScreenshot which will be a subimage defined by a specified by the rectangular region:
- x: the X coordinate of the upper-left corner of the specified rectangular region -
point.getX()
- 104
- y: the Y coordinate of the upper-left corner of the specified rectangular region -
point.getY()
- 744
- w: the width of the specified rectangular region - elementWidth - 340
- h: the height of the specified rectangular region - elementHeight - 486
So, the expected height of the BufferedImage
is turning out to be 744
+ 486
= 1230
which is pretty much out of the Raster. Hence you see the error.
Solution
To take a screenshot of a specific element or a particular div using selenium and java you can use the AShot()
method importing ashot-1.4.4.jar while working with Selenium Java Client v3.14.0, ChromeDriver v2.41, Chrome v 68.0.
Note: AShot()
method from ashot-1.4.4.jar works only with jQuery enabled Web Applications.
Code Block:
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();
}
}
References
You can find a couple of relevant discussions in:
Outro
You can find a detailed discussion of all the Java based methods of taking screenshot in How to take screenshot with Selenium WebDriver