wxPython用于让用户选择一个屏幕区域,然后调用pyautogui的screenshot进行截图。保持半秒(理想状态)截一张tmp图片比较上一张是否发生了变化,如果有变化,保存。
本例:macos10.14、python3.7.2、wxPython4.1.1、PyAutoGUI0.9.53、Pillow7.2.0
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 |
import math import os import platform import pyautogui # PyAutoGUI0.9.53 import threading import time import wx # wxPython4.1.1 from PIL import Image # Pillow7.2.0 class Shotor: def __init__(self): self.desktop = self.get_desktop() self.last_screenshot_path = None def get_desktop(self): # 保存到桌面 if(platform.system() == 'Windows'): import winreg key = winreg.OpenKey(winreg.HKEY_CURRENT_USER, r'Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders') return winreg.QueryValueEx(key, "Desktop")[0] else: return os.path.join(os.path.expanduser('~'), "Desktop") def pixel_equal(self, image1, image2, x, y): # 比较像素 piex1 = image1.load()[x, y] # 取像素点 piex2 = image2.load()[x, y] threshold = 10 # 阈值 if abs(piex1[0] - piex2[0]) < threshold and \ abs(piex1[1] - piex2[1]) < threshold and \ abs(piex1[2] - piex2[2]) < threshold: # 如果像素点的RGB值小于阈值,就认为像素点是一样的 return True else: return False def compare(self, image1, image2): # 根据像素比较图片 count = 0 # 全部像素点个数 same_count = 0 # 相同像素点个数 diff_count = 0 # 不同像素点个数 step = 2 # 视情况优化 for i in range(image1.size[0], step=step): for j in range(image1.size[1], step=step): count += 1 if self.pixel_equal(image1, image2, i, j): same_count += 1 else: diff_count += 1 same_rate = same_count / count # 相同像素占比 diff_rate = diff_count / count # 不同像素占比 return same_rate, diff_rate def shot(self, x, y, w, h): thread = threading.Thread(target=self.shotThread, args=[x, y, w, h]) thread.setDaemon(True) thread.start() # 子线程去截图。否则阻塞UI def shotThread(self, x, y, w, h): image = pyautogui.screenshot( region=(x*2, y*2, w*2, h*2)) # 为什么截图定位偏移为1/2 ? tmp_path = os.path.join(self.desktop, "diffshot_tmp.png") image.save(tmp_path) if self.last_screenshot_path: image1 = Image.open(tmp_path) image2 = Image.open(self.last_screenshot_path) same_rate, diff_rate = self.compare(image1, image2) if same_rate < 1: # 如果图片比较有新内容,就保存此截图 self.saveShot(image) else: self.saveShot(image) time.sleep(0.5) self.shot(x, y, w, h) def saveShot(self, image): screenshot_path = os.path.join( self.desktop, "diffshot_{}.png".format(time.time())) image.save(screenshot_path) self.last_screenshot_path = screenshot_path print("截图1张") class EventManager: def __init__(self): self.shot_x = 0 self.shot_y = 0 self.shot_w = 0 self.shot_h = 0 self.down_x = 0 self.down_y = 0 self.isDrawing = False _app = wx.App() # 首先进行初始化操作 ws = wx.DisplaySize() self.width = ws[0] self.height = ws[1] _frame = wx.Frame(None, -1, "比较截图") _frame.ShowFullScreen(True) _frame.SetTransparent(200) _frame.SetBackgroundStyle(wx.BG_STYLE_CUSTOM) _frame.Bind(wx.EVT_MOUSE_EVENTS, self.mouseEvent) # 监听鼠标事件 _bmp = wx.Bitmap(self.width, self.height) _staticBmp = wx.StaticBitmap(_frame, wx.ID_ANY, _bmp) self.buffer_bmp = _bmp self.staticBmp = _staticBmp self.frame = _frame self.app = _app self.drawButtons() def exitEvent(self, event): self.frame.Destroy() def showFullRect(self): self.frame.Show() self.app.MainLoop() def mouseEvent(self, event): if event.LeftDown(): pos = event.GetPosition() self.down_x = pos[0] self.down_y = pos[1] self.drawButtons() # 重绘按钮,会清除ClientDC绘制的图形 self.isDrawing = True elif event.LeftUp(): self.drawRect(event, True) self.isDrawing = False elif event.Dragging(): if self.isDrawing: self.drawRect(event) def drawButtons(self): _button_exit = wx.Button(self.frame, -1, "退出", pos=(50, self.height - 90)) _button_exit.Bind(wx.EVT_BUTTON, self.exitEvent) self.button_shot = wx.Button( self.frame, -1, "截图", pos=(50 + 100, self.height - 90)) self.button_shot.Bind(wx.EVT_BUTTON, self.shotEvent) def drawRect(self, event, isUp=False): pos = event.GetPosition() up_x = pos[0] up_y = pos[1] x = self.down_x y = self.height-self.down_y w = up_x - self.down_x h = self.down_y - up_y paint = wx.ClientDC(self.staticBmp) # 如果ClientDC使用Clear方法,会导致按钮也清除 paint.DrawRectangle(x, y, w, h) # self.frame.SetTransparent(60) # 提高透明度 if isUp: x = min(self.down_x, up_x) # pyautogui截图从左上角开始 y = min(self.down_y, up_y) w = math.fabs(self.down_x - up_x) h = math.fabs(self.down_y - up_y) self.shot_x = x self.shot_y = y self.shot_w = w self.shot_h = h def shotEvent(self, event): self.button_shot.Unbind(wx.EVT_BUTTON) self.frame.Unbind(wx.EVT_MOUSE_EVENTS) Shotor().shot(self.shot_x, self.shot_y, self.shot_w, self.shot_h) if "__main__" == __name__: EventManager().showFullRect() |
- end
声明
本文由崔维友 威格灵 cuiweiyou vigiles cuiweiyou 原创,转载请注明出处:http://www.gaohaiyan.com/3164.html
承接App定制、企业web站点、办公系统软件 设计开发,外包项目,毕设