Java+Selenium根据元素创建指定区域截图——Element快照

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. 退而求其次,只截图全屏可见区域

方法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;

    }

}

posted @ 2020-04-30 08:58  明月,  阅读(2402)  评论(0编辑  收藏  举报