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

需要注意的是:

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

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

相关推荐
清水白石0082 小时前
《从零到进阶:Pydantic v1 与 v2 的核心差异与零成本校验实现原理》
数据库·python
昵称已被吞噬~‘(*@﹏@*)’~2 小时前
【RL+空战】学习记录03:基于JSBSim构造简易空空导弹模型,并结合python接口调用测试
开发语言·人工智能·python·学习·深度强化学习·jsbsim·空战
2501_941877983 小时前
从配置热更新到运行时自适应的互联网工程语法演进与多语言实践随笔分享
开发语言·前端·python
酩酊仙人3 小时前
fastmcp构建mcp server和client
python·ai·mcp
格林威3 小时前
传送带上运动模糊图像复原:提升动态成像清晰度的 6 个核心方案,附 OpenCV+Halcon 实战代码!
人工智能·opencv·机器学习·计算机视觉·ai·halcon·工业相机
且去填词3 小时前
DeepSeek API 深度解析:从流式输出、Function Calling 到构建拥有“手脚”的 AI 应用
人工智能·python·语言模型·llm·agent·deepseek
rgeshfgreh4 小时前
Python条件与循环实战指南
python
rgeshfgreh4 小时前
通达信LC1文件结构解析指南
python
棒棒的皮皮4 小时前
【深度学习】YOLO模型速度优化Checklist
人工智能·深度学习·yolo·计算机视觉
七夜zippoe4 小时前
事件驱动架构:构建高并发松耦合系统的Python实战
开发语言·python·架构·eda·事件驱动