Java+Selenium根据元素创建指定区域截图——Element快照
执行步骤
获取全屏的截图
File screen = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
BufferedImage image = ImageIO.read(screen);
获取element的宽高以及坐标
创建一个WebElement元素,并且获取元素的高度,宽度,坐标信息
并且使用元素的高度和宽度创建一个矩形
WebElement element = driver.findElement(By.id("su"));
//获取元素的高度、宽度
int width = element.getSize().getWidth();
int height = element.getSize().getHeight();
//创建一个矩形使用上面的高度,和宽度
Rectangle rect = new Rectangle(width, height);
//元素坐标
Point p = element.getLocation();
裁剪全屏截图
最后根据元素位置对整个图片进行裁剪,创建一个element快照
如果元素过大,超过全屏截图的范围,这一步会报错(y + height) is outside or not,x+width同样也会报错
try{
BufferedImage img = image.getSubimage(p.getX(), p.getY(), rect.width, rect.height);
ImageIO.write(img, "png", screen);
}catch (Exception e){
e.printStackTrace();
}
元素过大的解决方案
创建全屏截图时,根据滚动条创建长截图
创建多个截图,拼接成长截图
退而求其次,只截图全屏可见区域
方法1和方法2暂时不作解释
这里对方法3描述一下
首先对元素的宽高,point的坐标简单化
int w = rect.width; //指定矩形区域的宽度
int h = rect.height;//指定矩形区域的高度
int x = p.getX(); //指定矩形区域左上角的X坐标
int y = p.getY(); //指定矩形区域左上角的Y坐标
初始化浏览器的分辨率
//driver的分辨率,这里设置1920*1080
int w_driver = 1920;
int h_driver = 1080;
如果元素的宽加上坐标X或者元素的高加上坐标Y超过浏览器的分辨率,对元素的大小进行调整
if ( y + h > h_driver){ //(y + height) is outside or not
h = h- (y + h - h_driver);
}
if (x + w > w_driver){
w = x - (x + w - w_driver); //(x + width) is outside or not
}
开始裁剪
try{
BufferedImage img = image.getSubimage(x, y, w, h);
ImageIO.write(img, "png", screen);
}catch (IOException e){
// TODO Auto-generated catch block
e.printStackTrace();
}
完整代码
package common;
import org.apache.commons.io.FileUtils;
import org.openqa.selenium.*;
import org.openqa.selenium.Point;
import org.openqa.selenium.chrome.ChromeDriver;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.awt.image.RasterFormatException;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class ElementSnapshot {
public static WebDriver driver;
/**
* main()方法调用
*
*/
public static void main(String[] args) throws Exception {
driver = new ChromeDriver();
driver.get("https://www.baidu.com");
driver.manage().window().maximize();
WebElement element = driver.findElement(By.id("su"));
String fileName = "filename";
//创建元素快照
elementSnapshot(driver,element);
//移动图片到指定位置
FileUtils.copyFile(elementSnapshot(driver,element), new File(fileName, System.currentTimeMillis()+".png"));
}
/**
* 根据Element截图指定区域方法
*
* @param driver
* @param element 截图区域
* @throws Exception
*/
public static File elementSnapshot(WebDriver driver, WebElement element) throws Exception {
//创建全屏截图
File screen = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
BufferedImage image = ImageIO.read(screen);
//获取元素的高度、宽度
int width = element.getSize().getWidth();
int height = element.getSize().getHeight();
//创建一个矩形使用上面的高度,和宽度
Rectangle rect = new Rectangle(width, height);
//元素坐标
Point p = element.getLocation();
//对前面的矩形进行操作
//TODO 使用可以截全图的方法(滚动条),暂未找到方式
int w = rect.width; //指定矩形区域的宽度
int h = rect.height;//指定矩形区域的高度
int x = p.getX(); //指定矩形区域左上角的X坐标
int y = p.getY(); //指定矩形区域左上角的Y坐标
//driver的分辨率,这里设置1920*1080
int w_driver = 1920;
int h_driver = 1080;
System.out.println("width:" + w);
System.out.println("height:"+ h);
System.out.println("x:"+ x);
System.out.println("y:"+ y);
System.out.println("y+height:"+(y + h));
System.out.println("x+width:"+ (x + w));
/**
* 如果Element的Y坐标值加上高度超过driver的高度
* 就会报错(y + height) is outside or not
* 退而求其次,调整图片的宽度和高度, 调整到适合driver的分辨率
* 此时会截图driver可见的元素区域快照
* TODO 如果能找到跨滚动条截图的方式,可以不用裁剪
*/
try{
if ( y + h > h_driver){
h = h- (y + h - h_driver); //
System.out.println("修改后的height:" + h);
System.out.println("修改后的y+height:"+ (y+h));
}
//(x + width) is outside or not
if (x + w > w_driver){
w = x - (x + w - w_driver);
System.out.println("修改后的width:"+ w);
System.out.println("修改后的x+width:"+ (x+w));
}
BufferedImage img = image.getSubimage(x, y, w, h);
ImageIO.write(img, "png", screen);
System.out.println("Screenshot By element success");
}catch (IOException e){
// TODO Auto-generated catch block
e.printStackTrace();
}
return screen;
}
}