Cropping screenshot around element - problems when using default Java classes?

2,032 views
Skip to first unread message

David

unread,
Apr 14, 2014, 4:19:15 PM4/14/14
to webd...@googlegroups.com
I was wondering if anyone has experienced issues with cropping WebDriver page screenshots around elements using the native Java classes for it (e.g. BufferedImage.getSubimage() ). The basic example is to pass in the element's x,y coordinates and it's width/height size to crop to.

The funny thing is sometimes, I get exceptions like "RasterFormatException: (x + width) is outside Raster" for this type of implementation. 

But it doesn't happen all the time, and may be specific to certain browsers at times, I forget, haven't run recently. And even when it does work, the resulting cropped screenshot varies across browsers, so you never get the exact same cropped image across browsers, but that's a separate issue. 

Interestingly, I never saw such raster exception issue using other libraries like http://www.javaxt.com/javaxt-core/javaxt.io.Image/

I've not heard of anyone mentioning issues using the native Java method to crop screenshots for WebDriver. Am I the only one to experience this issue?

darrell

unread,
Apr 15, 2014, 9:46:56 AM4/15/14
to webd...@googlegroups.com
I typically keep everything when I do a screenshot. Cropping the image doesn't make a lot of sense to me because it loses information. I'm usually doing screenshots when something fails. I want to be able to see what is on the screen when the failure occurs. So I tend not to know what I'm looking at. So getting the full screen is the behavior I'm looking for.

It could also be that you are looking in the wrong place for your answer. Your question really has nothing to do with WebDriver. You have an image and you are trying to crop it. The fact that the image was created by WebDriver isn't really relevant to your problem. So maybe you need to search forums which deal with your image cropping library.

Purusothaman Ramanujam

unread,
Apr 15, 2014, 1:02:31 PM4/15/14
to webd...@googlegroups.com
As Darrell mentioned, cropping the image to have only element related image will not help much to identify the issue from the screenshot. 

If you are concerned about the file size you can consider scaling down the image quality.

Shashank Shekhar Tiwari

unread,
Apr 16, 2014, 11:52:56 AM4/16/14
to webd...@googlegroups.com
Hi,

there is no need to use native java class for cropping .

follow below code for cropping using WebDriver

WebElement leftTopCornerOfTheImage = driver.findElement(By.id("imageToBeCropped")); 
Actions actions = new Actions(driver); 
actions.clickAndHold(leftTopCornerOfTheImage).moveByOffset(12, 25).perform(); 

above code is well tested.



On Tuesday, April 15, 2014 1:49:15 AM UTC+5:30, David wrote:

David

unread,
Apr 16, 2014, 1:59:43 PM4/16/14
to webd...@googlegroups.com
Shashank,

Your code does not highlight where the screenshot comes into play. That just looks like a drag & drop operation that clicks top left corner of image to desired offset to highlight/select the image area but does nothing thereafter.

Also, that code won't work for those that need to support Safari because SafariDriver does not yet support the Actions API classes.

David

unread,
Apr 16, 2014, 2:05:01 PM4/16/14
to webd...@googlegroups.com
Darrell,

The reason I post here is because the code being used is the same boilerplate code suggested by others to crop images in Java for WebDriver screenshots. Yet, I've been the only one (it seems) that have experienced failures in the cropping. Surely if this is common code, others would have ran into it as well? So I'm just asking for stats/reproducibility of the issue.

As for why one would want to crop screenshots? For things like image comparison, which is much harder to do against a full page screenshot. Ideally, I'd prefer to download the image (outside Selenium but using Selenium to get the URL) and use that, but there are cases where the "image" is not a real standalone image for download but part of something bigger or like rendered sprite that can't be downloaded as an image. And now, why would one want to do image comparison? If your site/application is based heavily on image rendering as a feature/service, you're going to want to ensure it works right. Granted you can cover that with manual testing instead, but it is always nice to try to automate as effectively as possible. But most sites/people are focused on image rendering, so that's usually not a concern for them.

darrell

unread,
Apr 17, 2014, 9:44:52 AM4/17/14
to webd...@googlegroups.com
This is the first I've heard of someone cropping screen captures from Selenium. I know there are plenty of tools out there which will capture regions of a screen and compare it against a baseline. I would use something like Wraith for this purpose.

Regardless, if you aren't getting the response you desire from this google group, you should consider going to a group which has more expertise with the library you are using. You should, statistically, have a better chance of getting the help you need.

David

unread,
Apr 19, 2014, 6:23:42 PM4/19/14
to webd...@googlegroups.com
Thanks for the advice Darrell. I'll keep that in mind.

FYI, the reason the screenshots are cropped is to eliminate needless noise & variance, since the image of interest is what is cropped, not the entire page. And generally, irrespective of the screen resolution, the cropped element is still the same dimensions (at least for our sites). If only Selenium offered built in capability to image snapshot a given element and not just the entire page, cropping wouldn't be necessary.

Shashank Shekhar Tiwari

unread,
Apr 20, 2014, 10:49:31 AM4/20/14
to webd...@googlegroups.com
Hi David,

Now i got the question and worked on that.

use below code , this code line will  never give "RasterFormatException: (x + width) is outside Raster"
Webelement image = driver.findElement(By.xpath("xpath")); 

 Point p = image.getLocation();
   BufferedImage cropImg = img.getSubimage(cropStartX, cropStartY, imageWidth-p.getX(),   
    imageHeight-p.getY());


(x + width) exception generate when Width  goes outside the original image's width 
in getSubimage method, width and height must be less than original one.

erki manniste

unread,
Apr 21, 2014, 3:36:17 AM4/21/14
to webd...@googlegroups.com
Yea, i have done it, you can check my implementation here http://stackoverflow.com/questions/3422262/take-a-screenshot-with-selenium-webdriver/21376753#21376753 and here https://groups.google.com/forum/#!topic/selenium-users/rZlCFGv_IBI

afaik, you get the rasterFormatException when the points you give to getSubImage are out of bounds for the given bufferedImage, similar to indexOutOfBounds for array or smth. Probably a multiple monitor issue.

good luck
e.

David

unread,
Apr 21, 2014, 1:08:44 PM4/21/14
to webd...@googlegroups.com
Thanks Shashank, I'll give that a try and see if it works for my case avoiding exception and still giving the right cropping.

David

unread,
Apr 21, 2014, 1:13:07 PM4/21/14
to webd...@googlegroups.com
Thanks for the feedback erki. It didn't occur to me multiple monitors could pose an issue here, that may likely be my problem as I do have multiple monitor setup.

R.Purushothaman

unread,
Apr 20, 2014, 10:56:08 AM4/20/14
to webd...@googlegroups.com
The purpose of this is to take screenshot when there is an failed step.

What if there is no such element and we get nosuchelement exception? We will not be getting the screenshot right?

Thanks,
R.Purusothaman


--
You received this message because you are subscribed to a topic in the Google Groups "webdriver" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/webdriver/I45Md4ICjJ0/unsubscribe.
To unsubscribe from this group and all its topics, send an email to webdriver+...@googlegroups.com.
To post to this group, send email to webd...@googlegroups.com.
Visit this group at http://groups.google.com/group/webdriver.
For more options, visit https://groups.google.com/d/optout.

David

unread,
Apr 23, 2014, 3:00:41 PM4/23/14
to webd...@googlegroups.com
That is somewhat correct R.Purusothaman. We capture screenshot first then crop it. So by implementation, if you catch the exception you still have the screenshot available, just uncropped. If you don't, you still have the uncropped screenshot also, but the test stops due to exception, and the system (Java/WebDriver) may tend to delete the screenshot file, if you saved it as a "temp" file, and if not, you'd still have it in the file system. And depending on the framework used, if it takes screenshot on exceptions/failures, you may get yet another screenshot when the element exception occurs for the cropping step.

Though one must acknowledge that Selenium WebDriver is not just a test tool, it can be used for automation for other purposes too. Others have used it for said other purposes though the majority is for testing. And as such, taking screenshots, while intended for test failures, is not solely restricted to such. It can be used to capture and assess or compare against known benchmark reference screenshots, whether that be manual or automated. Or for archival purposes to view the state of the site/browser at any given time, even for successful tests.

erki manniste

unread,
Apr 26, 2014, 10:59:05 PM4/26/14
to webd...@googlegroups.com
@R.purusoman
hehee, if the element is not found and you want to take a picture of it, then what is the thing that you are taking the picture of? : ), it is something like.. you can not drive a car if you don't have any cars or whatever.

But generally speaking, say you usually have the element available but due to some bug, not this time, I see no problem here as the minimum you would have to pass to the method that is taking screenshot is the original screenshot and the location of that element. Anyway, probably the most reasonable way to implement this is to pass the WebElement under question to screenshot method, take screenshot of everything and then crop it. In this case, stuff like NoSuchElement or NullPointer or whatever should be handled before hand. So it would look like either:

... inside some method
if (webElement != null)
    takeScreenshotOfElement(webElement);

or if you want:
takeScreenshotOfElement(webElement);

...
takeScreenshotOfElement(WebElement element){
    if (element == null) return;
....
}

And taking the screenshot of the whole page should be handled by some other routine you implement. And, if your test fails, taking screenshot of whole page should be handled by your execution framework.


@David, did you solve that RasterFormatException?

br.
erki
Reply all
Reply to author
Forward
0 new messages