playwright+python UI自动化测试中实现图片颜色和像素对比

python 复制代码
def compare_image(expect_path, actual_path, output_path, color_diff_threshold=10.0,max_diff_pixels=100):
    # 读取图片
    img1 = cv2.imread(expect_path)
    img2 = cv2.imread(actual_path)
    if img1.shape != img2.shape:
        img2 = cv2.resize(img2, (img1.shape[1], img1.shape))

    # ---------------------- 颜色差异对比(LAB空间) ----------------------
    # 转换为LAB颜色空间(更贴近人类视觉)
    img1_lab = cv2.cvtColor(img1, cv2.COLOR_BGR2LAB)
    img2_lab = cv2.cvtColor(img2, cv2.COLOR_BGR2LAB)

    # 计算色差(欧氏距离)
    color_diff = np.sqrt(np.sum((img1_lab - img2_lab) ** 2, axis=2))
    mean_color_diff = np.mean(color_diff)

    if mean_color_diff > color_diff_threshold:
        # 增强色差可视化(将差异值映射到0-255)
        color_diff_vis = (color_diff * 255 / np.max(color_diff)).astype(np.uint8)
        cv2.imwrite(output_path, color_diff_vis)
        raise ValueError(f"颜色差异过大:{mean_color_diff:.2f} > {color_diff_threshold}")

    # ---------------------- 像素差异对比(灰度空间) ----------------------
    # 灰度化 + 模糊处理
    gray1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
    gray2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)
    blur1 = cv2.GaussianBlur(gray1, (5, 5), 0)
    blur2 = cv2.GaussianBlur(gray2, (5, 5), 0)

    # 计算像素差异
    diff = cv2.absdiff(blur1, blur2)
    _, thresh = cv2.threshold(diff, 25, 255, cv2.THRESH_BINARY)

    # 统计显著差异像素数
    diff_pixels = np.sum(thresh == 255)
    if diff_pixels > max_diff_pixels:
        # 标记差异区域(红框)
        contours, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
        result = img2.copy()
        for cnt in contours:
            # if cv2.contourArea(cnt) > min_contour_area:
            x, y, w, h = cv2.boundingRect(cnt)
            cv2.rectangle(result, (x, y), (x + w, y + h), (0, 0, 255), 2)
        cv2.imwrite(output_path, result)
        raise ValueError(f"差异像素数超过阈值:{diff_pixels} > {max_diff_pixels}")

1、准备好基线图(expect_path)

2、playwright打开页面,截取元素图片(actual_path)

3、直接将基线图和实际元素图片传入对比方法对比,当差异超过预期,则会在实际元素图片上红框标记出差异部分保存到output_path

需要注意的是:

如果是表单截图,则需要等待所有的字段都加载完

如果是图片预览截图,则需要等待图片彻底打开到最大

相关推荐
好家伙VCC1 天前
### WebRTC技术:实时通信的革新与实现####webRTC(Web Real-TimeComm
java·前端·python·webrtc
前端玖耀里1 天前
如何使用python的boto库和SES发送电子邮件?
python
serve the people1 天前
python环境搭建 (十二) pydantic和pydantic-settings类型验证与解析
java·网络·python
小天源1 天前
Error 1053 Error 1067 服务“启动后立即停止” Java / Python 程序无法后台运行 windows nssm注册器下载与报错处理
开发语言·windows·python·nssm·error 1053·error 1067
喵手1 天前
Python爬虫实战:HTTP缓存系统深度实战 — ETag、Last-Modified与requests-cache完全指南(附SQLite持久化存储)!
爬虫·python·爬虫实战·http缓存·etag·零基础python爬虫教学·requests-cache
喵手1 天前
Python爬虫实战:容器化与定时调度实战 - Docker + Cron + 日志轮转 + 失败重试完整方案(附CSV导出 + SQLite持久化存储)!
爬虫·python·爬虫实战·容器化·零基础python爬虫教学·csv导出·定时调度
2601_949146531 天前
Python语音通知接口接入教程:开发者快速集成AI语音API的脚本实现
人工智能·python·语音识别
寻梦csdn1 天前
pycharm+miniconda兼容问题
ide·python·pycharm·conda
Java面试题总结1 天前
基于 Java 的 PDF 文本水印实现方案(iText7 示例)
java·python·pdf
不懒不懒1 天前
【决策树算法实战指南:从原理到Python实现】
python·决策树·id3·c4.5·catr