需求与实现:
需求:以自动化或工具的方式实现页面UI与标准UI图对比并输出可视结果
实现:
目前实现:
- 可将站点与标准UI图对比
- 可将两站点对比
- 可将两UI图对比
可应用的实际场景:
- 站点迁移,对比两个站点页面
- 版本迭代,前后UI对比
- 实际站点页面与标准UI图对比
- 可通过Appnium或Airtest应用到移动端页面对比
相关技术:
ImageChops :
主要包括对图片的算术运算,叫做通道运算(channel operations)。可以用于多种途径,包括一些特效制作,图片整合,算数绘图等等方面。这里用到了该模块的切换图片位深 功能以及图片对比功能;
Selenium:
结合webdriver 进行浏览器驱动,实现 web端登录->页面跳转->html页面在线保存为图片 整体流程;
效果展示:
Web页面自动截取为图片:
webnew.png:
页面与标准ui图对比:
差异数值获取:
差异图获取:
完全一致:
差异时:
web界面对比图:
web差异图:
手机界面对比图:
手机界面差异图:
注:对比手机ui图时,上方状态栏时间或其他部分的无效差异,可以通过截取指定区域进行规避。
主要方法解析:
ImageChopsPic
def compare_images(path_one, path_two, diff_save_location): """ 比较图片,如果有不同则生成展示不同的图片 @参数一: path_one: 第一张图片的路径 @参数二: path_two: 第二张图片的路径 @参数三: diff_save_location: 差异图片的保存路径 """ image_one = Image.open(path_one) image_two = Image.open(path_two) try: diff = ImageChops.difference(image_one, image_two) if diff.getbbox() is None: # 图片间没有任何不同则直接退出 print(image_one, image_two, "对比图片完全相同!") else: print("差异图保存为:", diff_save_location) diff.save(diff_save_location) except ValueError as e: text = (" 当前图片大小或位深不一致 ") print("【{0}】{1}".format(e, text)) # 由于模块限制需要强制转换图片位深为'RGB:24'保证可识别且位深一致 def picture(path_change_bf, path_change_af): img = Image.open(path_change_bf).convert('RGB') # 输出当前图片位深 print(img.getbands()) img.save(path_change_af) print("位深已强制转换为 RGB:24")
ImageChopsValues
# 输出当前对比图片的差异值,数值越大表明图片差异越大,无位深识别限制 def image_contrast(img1, img2): image1 = Image.open(img1) image2 = Image.open(img2) h1 = image1.histogram() h2 = image2.histogram() result = math.sqrt(reduce(operator.add, list(map(lambda a, b: (a - b) ** 2, h1, h2))) / len(h1)) return result
ChangPic
""" 批量改变目录下图片位深 ,保存到新的目录下 函数解释: path :图片存放的路径 newpath :转化完成后,存放的路径 convert :需要更改成那一种为深度的图片的格式 """ def picture(path, newpath): files = os.listdir(path) for i in files: files = os.path.join(path, i) img = Image.open(files).convert('RGB') dirpath = newpath file_name, file_extend = os.path.splitext(i) dst = os.path.join(os.path.abspath(dirpath), file_name + '.png') img.save(dst) print("已将",i,"强制转为RGB格式")
WebToPic
# 截取网页照片函数 def screen_shot(url, png_name): brower = webdriver.Chrome() # 使用get()方法,打开指定页面。 brower.get(url) # 设置浏览器全屏显示 brower.maximize_window() time.sleep(1) # 获取登录tab并点击 gofor = brower.find_element_by_xpath('//*[@id="app"]/div/div/div[2]/div/div/div[2]/div[1]/div/div[1]/div/div/div/div/div[3]') gofor.click() time.sleep(1) # 获取用户名输入框并输入 name = brower.find_element_by_xpath('//*[@id="app"]/div/div/div[2]/div/div/div[2]/div[1]/div/div[2]/div[2]/div/div/div[2]/form/input[1]') name.send_keys("13120210916") # 获取密码输入框并输入 password = brower.find_element_by_xpath('//*[@id="app"]/div/div/div[2]/div/div/div[2]/div[1]/div/div[2]/div[2]/div/div/div[2]/form/input[2]') password.send_keys("hly12345") # 获取登录按钮并点击 login_button = brower.find_element_by_xpath('//*[@id="app"]/div/div/div[2]/div/div/div[2]/div[1]/div/div[2]/div[2]/div/div/button') login_button.click() time.sleep(1) # 打开目标页 brower.get(url) time.sleep(2) # 使用save_screenshot将浏览器正文部分截图,即使正文本分无法一页显示完全,save_screenshot也可以完全截图 brower.save_screenshot(png_name) # 关闭浏览器 brower.close()
附:
关于Pillow库(ImageChops)的详细文档:
https://pillow.readthedocs.io/en/latest/index.html
关于图片 位深 的解释:
https://blog.csdn.net/WoHongG/article/details/84074057
https://blog.csdn.net/weixin_39190382/article/details/105917690
关于ImageChops功能使用的注意事项:
- 对比图 位深需小于等于24(RGB)
- 强制转换 位深功能,需原对比图 位深相等,否则会出现像素点错位导致对比误差
- 无效对比区域可以通过截取功能来规避