导读:本期聚焦于小伙伴创作的《如何用Python实现自动化截图对比?PIL图像差异检测》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《如何用Python实现自动化截图对比?PIL图像差异检测》有用,将其分享出去将是对创作者最好的鼓励。

自动化截图对比是很多场景下都需要用到的功能,比如UI自动化测试验证页面渲染是否正确、监控系统检测页面是否出现异常变化等。借助Python的PIL库,我们可以快速实现图像差异检测的能力,完成两张截图的对比工作。

如何用Python实现自动化截图对比?PIL图像差异检测

实现原理概述

基于PIL的图像差异检测核心思路是:先将两张待对比的图像转换为相同的尺寸和色彩模式,再逐像素对比两个图像对应位置的像素值,统计差异像素的数量和位置,最后根据需求输出差异结果,比如生成标记了差异区域的对比图、返回差异像素占比等。

环境准备

首先需要安装PIL库,现在常用的PIL分支是Pillow,安装命令如下:

pip install pillow

基础截图对比实现

1. 获取截图

如果是对比本地已有的两张截图,可以直接读取;如果需要实时截图,可以结合pyautogui等库实现,这里先演示读取本地图像的场景。以下代码实现两张图像的读取和基础对比:

from PIL import Image

def load_image(image_path):
    # 打开图像并转换为RGB模式,避免不同色彩模式导致对比异常
    img = Image.open(image_path).convert("RGB")
    return img

# 读取两张待对比的截图
img1 = load_image("./screenshot1.png")
img2 = load_image("./screenshot2.png")

# 确保两张图像尺寸一致,不一致则调整第二张图像尺寸和第一张相同
if img1.size != img2.size:
    img2 = img2.resize(img1.size)

# 获取图像尺寸
width, height = img1.size

2. 逐像素对比计算差异

接下来逐像素对比两个图像的像素值,统计差异像素的数量和位置:

def compare_images(img1, img2, diff_threshold=30):
    width, height = img1.size
    diff_pixels = []  # 存储差异像素的坐标
    total_diff = 0    # 差异像素总数
    
    # 遍历所有像素
    for x in range(width):
        for y in range(height):
            pixel1 = img1.getpixel((x, y))
            pixel2 = img2.getpixel((x, y))
            # 计算RGB三个通道的差值总和
            diff_sum = abs(pixel1[0] - pixel2[0]) + abs(pixel1[1] - pixel2[1]) + abs(pixel1[2] - pixel2[2])
            # 差值超过阈值则判定为差异像素
            if diff_sum > diff_threshold:
                diff_pixels.append((x, y))
                total_diff += 1
    
    return diff_pixels, total_diff

# 执行对比,阈值设为30,可根据实际场景调整
diff_pixels, total_diff = compare_images(img1, img2, diff_threshold=30)
print(f"差异像素总数:{total_diff}")
print(f"差异像素占比:{total_diff / (width * height) * 100:.2f}%")

3. 生成差异标记图

为了更直观地看到差异位置,可以生成一张标记了差异区域的图像,将差异像素标记为红色:

def generate_diff_image(img1, diff_pixels):
    # 复制第一张图像作为基础
    diff_img = img1.copy()
    # 将差异像素标记为红色
    for x, y in diff_pixels:
        diff_img.putpixel((x, y), (255, 0, 0))
    return diff_img

# 生成差异图并保存
diff_img = generate_diff_image(img1, diff_pixels)
diff_img.save("./diff_result.png")
print("差异标记图已保存为diff_result.png")

优化方案

1. 提升对比效率

上面的逐像素循环方式在图像尺寸较大时效率较低,可以借助numpy库将图像转换为数组后批量计算,提升运行速度:

import numpy as np
from PIL import Image

def fast_compare_images(img1, img2, diff_threshold=30):
    # 转换为numpy数组
    arr1 = np.array(img1)
    arr2 = np.array(img2)
    # 计算像素差值,取绝对值后求和
    diff_arr = np.abs(arr1 - arr2)
    diff_sum = np.sum(diff_arr, axis=2)
    # 找到差异像素的位置
    diff_mask = diff_sum > diff_threshold
    total_diff = np.sum(diff_mask)
    diff_pixels = list(zip(*np.where(diff_mask)[::-1]))  # 转换为(x,y)坐标格式
    return diff_pixels, total_diff

# 使用优化后的方法对比
diff_pixels_fast, total_diff_fast = fast_compare_images(img1, img2, diff_threshold=30)
print(f"优化后差异像素总数:{total_diff_fast}")

2. 忽略指定区域差异

如果截图中有一些固定变化的区域,比如时间戳、动态广告位,可以在对比前将这些区域屏蔽,只对比有效区域。以下代码实现指定区域忽略:

def compare_with_ignore(img1, img2, ignore_areas, diff_threshold=30):
    width, height = img1.size
    diff_pixels = []
    total_diff = 0
    
    for x in range(width):
        for y in range(height):
            # 判断当前像素是否在忽略区域内
            is_ignored = False
            for (start_x, start_y, end_x, end_y) in ignore_areas:
                if start_x <= x <= end_x and start_y <= y <= end_y:
                    is_ignored = True
                    break
            if is_ignored:
                continue
            # 正常对比逻辑
            pixel1 = img1.getpixel((x, y))
            pixel2 = img2.getpixel((x, y))
            diff_sum = abs(pixel1[0] - pixel2[0]) + abs(pixel1[1] - pixel2[1]) + abs(pixel1[2] - pixel2[2])
            if diff_sum > diff_threshold:
                diff_pixels.append((x, y))
                total_diff += 1
    return diff_pixels, total_diff

# 定义要忽略的区域,格式为(起始x,起始y,结束x,结束y)
ignore_areas = [(100, 50, 300, 80)]  # 忽略左上角时间戳区域
diff_pixels_ignore, total_diff_ignore = compare_with_ignore(img1, img2, ignore_areas, diff_threshold=30)
print(f"忽略指定区域后差异像素总数:{total_diff_ignore}")

常见问题说明

  • 如果两张截图尺寸不一致,一定要先统一尺寸再对比,否则会出现索引错误或者对比结果无意义。
  • 阈值diff_threshold需要根据实际场景调整,图像压缩、抗锯齿等效果可能会导致正常像素有微小差异,阈值设置过低会误判,过高会漏判。
  • 如果截图包含透明通道,建议先转换为RGB模式,避免透明通道对对比结果产生影响。

PythonPIL自动化截图图像差异检测图像对比修改时间:2026-07-22 03:30:33

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。