comon.py 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396
  1. # -*- coding: utf-8 -*-
  2. from datetime import datetime
  3. import threading
  4. import pyautogui
  5. import win32com
  6. from scriptBase.imgFind import pcacc_img
  7. from scriptBase.mouseClick import pcacc_mouse
  8. import time
  9. import random
  10. import pygetwindow as gw
  11. import re
  12. from PIL import Image
  13. from PIL import ImageFilter
  14. import io
  15. from scriptBase.ocr import *
  16. from scriptBase.record import ScreenRecorder
  17. import win32gui
  18. import win32con
  19. g_recorder = ScreenRecorder()
  20. def compress_image(image, target_size = 100 * 1024):
  21. # 调整图像尺寸,保持纵横比
  22. image.thumbnail((1024, 1024))
  23. # 尝试不同的压缩质量
  24. quality = 80
  25. compressed_image = io.BytesIO()
  26. while compressed_image.tell() < target_size and quality >= 10:
  27. image.save(compressed_image, format='JPEG', quality=quality)
  28. quality -= 10
  29. compressed_image.seek(0)
  30. compressed_size = len(compressed_image.getvalue())
  31. return compressed_image.getvalue()
  32. '''
  33. def binarize_image(image):
  34. # 将图片转换为黑白格式(二值化)
  35. # 这里使用Pillow库来进行图片二值化
  36. image = image.convert("L") # 将图片转换为灰度图像
  37. threshold = 128 # 设定二值化阈值,0~255之间,通常取128
  38. image = image.point(lambda x: 0 if x < threshold else 255, '1') # 进行二值化处理
  39. return image
  40. '''
  41. def binarize_image(image):
  42. # 将图片转换为灰度图像
  43. image = image.convert("L")
  44. # 降噪处理(中值滤波)
  45. image = image.filter(ImageFilter.MedianFilter(size=3))
  46. # 自适应阈值二值化
  47. threshold = image.point(lambda x: 0 if x < 128 else 255, '1')
  48. return threshold
  49. def waitFindImg(imgPath, waitTime, preWaitTime, isCV=False):
  50. pre = time.time()
  51. if preWaitTime > 0:
  52. myTimeSleep(preWaitTime)
  53. #sleep 0.2s per times
  54. curTime = 0
  55. while waitTime == -1 or curTime < waitTime:
  56. ret, pos_cur = pcacc_img.find_imgs(imgPath, isCV)
  57. if ret:
  58. return ret, pos_cur
  59. else:
  60. myTimeSleep(0.1)
  61. curTime = time.time() - pre
  62. costTime = time.time() - pre
  63. print(f"waitFindImg failed, cost:{costTime:.2f}, img:{imgPath}")
  64. return False, None
  65. def waitClickImg_noWait(imgPath, waitTime, preWaitTime, isCV=False):
  66. pre = time.time()
  67. if preWaitTime > 0:
  68. myTimeSleep(preWaitTime)
  69. #sleep 0.2s per times
  70. curTime = 0
  71. while waitTime == -1 or curTime < waitTime:
  72. ret, pos_cur = pcacc_img.find_imgs(imgPath, isCV)
  73. if ret:
  74. pcacc_mouse.click(pos_cur[0], pos_cur[1])
  75. myTimeSleep(0.5)
  76. return True, pos_cur
  77. else:
  78. myTimeSleep(0.1)
  79. curTime = time.time() - pre
  80. costTime = time.time() - pre
  81. print(f"waitClickImg_noWait failed, cost:{costTime:.2f}, img:{imgPath}")
  82. return False, (-1, -1)
  83. def waitFindImg_withBool(imgPath, waitTime, preWaitTime, isCV=False):
  84. ret, pos = waitFindImg(imgPath, waitTime, preWaitTime, isCV)
  85. return ret
  86. def waitClickImg_noWait_withBool(imgPath, waitTime, preWaitTime, isCV=False):
  87. ret, pos = waitClickImg_noWait(imgPath, waitTime, preWaitTime, isCV)
  88. return ret
  89. def waitclickMultiImg(imgArr, waitTime, preWaitTime):
  90. if preWaitTime > 0:
  91. myTimeSleep(preWaitTime)
  92. #sleep 0.2s per times
  93. curTime = 0
  94. while waitTime == -1 or curTime < waitTime:
  95. ret, pos_cur = pcacc_img.find_imgArr(imgArr)
  96. if ret:
  97. pcacc_mouse.click(pos_cur[0], pos_cur[1])
  98. myTimeSleep(0.5)
  99. ret, pos_cur = pcacc_img.find_imgArr(imgArr)
  100. if ret == False:
  101. return True, pos_cur
  102. pcacc_mouse.click(pos_cur[0], pos_cur[1])
  103. myTimeSleep(0.5)
  104. ret, pos_cur = pcacc_img.find_imgArr(imgArr)
  105. if ret == False:
  106. return True, pos_cur
  107. else:
  108. return True, pos_cur
  109. else:
  110. myTimeSleep(0.2)
  111. curTime = curTime + 0.2
  112. print("waitclickMultiImg failed", imgArr)
  113. return False, (-1, -1)
  114. def waitClickImg(imgPath, waitTime, preWaitTime, isCV=False):
  115. if preWaitTime > 0:
  116. myTimeSleep(preWaitTime)
  117. #sleep 0.2s per times
  118. curTime = 0
  119. while waitTime == -1 or curTime < waitTime:
  120. ret, pos_cur = pcacc_img.find_imgs(imgPath, isCV)
  121. if ret:
  122. pcacc_mouse.move_mouse(pos_cur[0], pos_cur[1])
  123. ret, pos_cur2 = pcacc_img.find_imgs(imgPath, isCV)
  124. if ret:
  125. pcacc_mouse.click(pos_cur2[0], pos_cur2[1])
  126. else:
  127. pcacc_mouse.click(pos_cur[0], pos_cur[1])
  128. myTimeSleep(0.5)
  129. ret, pos_cur = pcacc_img.find_imgs(imgPath, isCV)
  130. if ret == False:
  131. return True, pos_cur
  132. pcacc_mouse.move_mouse(pos_cur[0], pos_cur[1])
  133. ret, pos_cur2 = pcacc_img.find_imgs(imgPath, isCV)
  134. if ret:
  135. pcacc_mouse.click(pos_cur2[0], pos_cur2[1])
  136. else:
  137. pcacc_mouse.click(pos_cur[0], pos_cur[1])
  138. myTimeSleep(0.5)
  139. ret, pos_cur = pcacc_img.find_imgs(imgPath, isCV)
  140. if ret == False:
  141. return True, pos_cur
  142. else:
  143. return True, pos_cur
  144. else:
  145. myTimeSleep(0.2)
  146. curTime = curTime + 0.2
  147. print("waitClickImg failed", imgPath)
  148. return False, (-1, -1)
  149. def waitClickImg_withBool(imgPath, waitTime, preWaitTime, isCV=False):
  150. ret, pos = waitClickImg(imgPath, waitTime, preWaitTime, isCV)
  151. return ret
  152. def myTimeSleep(curTime , FunStatus=None):
  153. tmpTime = curTime * 1000
  154. randomTime = random.randint(int(tmpTime - tmpTime / 9), int(tmpTime + tmpTime / 9)) / 1000
  155. randomTime = round(randomTime)
  156. while randomTime > 50:
  157. time.sleep(50)
  158. randomTime -= 50
  159. showStr = f'下一轮{randomTime}s'
  160. if FunStatus is not None:
  161. FunStatus(showStr)
  162. print(showStr)
  163. time.sleep(randomTime)
  164. def myTimeSleep_small():
  165. time.sleep(random.randint(200, 1000) / 1000)
  166. def myTimeSleep_big():
  167. time.sleep(random.randint(1200, 2000) / 1000)
  168. def get_random_point(region):
  169. left, top, width, height = region
  170. x = random.randint(left, left + width)
  171. y = random.randint(top, top + height)
  172. return x, y
  173. def get_yys_random_point(region):
  174. dstRegion = yys_getRegion(region, True)
  175. print(dstRegion)
  176. return get_random_point(dstRegion)
  177. def maintain_state(min):
  178. state = True
  179. last_reset_time = time.time()
  180. def inner_func():
  181. nonlocal state, last_reset_time
  182. # 获取当前时间
  183. current_time = time.time()
  184. # 如果距离上次重置的时间大于等于min秒,则将状态重置为True
  185. if current_time - last_reset_time >= min:
  186. state = True
  187. last_reset_time = current_time
  188. # 返回状态值,并将状态置为False
  189. result = state
  190. state = False
  191. return result
  192. return inner_func
  193. def find_window_pos(title):
  194. # 查找窗口
  195. winList = gw.getWindowsWithTitle(title)
  196. if len(winList) == 0:
  197. return False, None
  198. window = gw.getWindowsWithTitle(title)[0] # 替换为你要查找的窗口标题
  199. # 获取位置信息
  200. left = window.left
  201. top = window.top
  202. width = window.width
  203. height = window.height
  204. # 打印位置信息
  205. #print(f'Left: {left}, Top: {top}, Width: {width}, Height: {height}')
  206. if left > 0 and top > 0 and width > 0 and height > 0:
  207. return True, (left, top, width, height)
  208. else:
  209. return False, None
  210. def find_yys_pos():
  211. return find_window_pos('MuMu安卓设备')
  212. def get_first_single_digit(string):
  213. pattern = r'\d' # 匹配一个独立的单个数字
  214. match = re.search(pattern, string)
  215. if match:
  216. return int(match.group()) # 将匹配到的字符串转换为整数
  217. else:
  218. return None
  219. def dragAuto(gamestr, positions, isQuick=False):
  220. tmpRet, tmpPos = find_window_pos(gamestr)
  221. if tmpRet == False:
  222. return False
  223. x1 = positions[0] + tmpPos[0] + random.randint(-20, 20)
  224. y1 = positions[1] + tmpPos[1] + random.randint(-20, 20)
  225. x2 = positions[2] + tmpPos[0] + random.randint(-20, 20)
  226. y2 = positions[3] + tmpPos[1] + random.randint(-20, 20)
  227. pcacc_mouse.drag_from(x1, y1, x2, y2, isQuick)
  228. return True
  229. def ocrAuto(gamestr, positions):
  230. try:
  231. tmpRet, tmpPos = find_window_pos(gamestr)
  232. if tmpRet == False:
  233. return []
  234. x1 = positions[0] + tmpPos[0]
  235. y1 = positions[1] + tmpPos[1]
  236. x2 = positions[2] + tmpPos[0]
  237. y2 = positions[3] + tmpPos[1]
  238. region = (x1, y1, x2, y2)
  239. lineStr = capture_and_ocr(region)
  240. print("识别到:", lineStr)
  241. except:
  242. lineStr = ""
  243. return lineStr
  244. def tryMoveTopWindow(gameStr):
  245. """尝试查找并置顶包含指定关键词的窗口"""
  246. mumu_windows = []
  247. def enum_callback(hwnd, param):
  248. """枚举回调函数"""
  249. if win32gui.IsWindowVisible(hwnd):
  250. window_title = win32gui.GetWindowText(hwnd)
  251. if gameStr in window_title:
  252. param.append((hwnd, window_title))
  253. return True
  254. # 枚举所有顶级窗口
  255. win32gui.EnumWindows(enum_callback, mumu_windows)
  256. if not mumu_windows:
  257. print(f"未找到包含 '{gameStr}' 的窗口")
  258. return False
  259. # 输出找到的窗口信息(调试用)
  260. print(f"找到 {len(mumu_windows)} 个匹配窗口:")
  261. for i, (hwnd, title) in enumerate(mumu_windows):
  262. print(f" {i+1}. 句柄: {hwnd}, 标题: {title}")
  263. # 处理第一个找到的窗口
  264. target_hwnd, target_title = mumu_windows[0]
  265. try:
  266. # 设置窗口置顶
  267. win32gui.SetWindowPos(target_hwnd, win32con.HWND_TOPMOST, 0, 0, 0, 0,
  268. win32con.SWP_NOMOVE | win32con.SWP_NOSIZE)
  269. # 激活窗口到前台
  270. try:
  271. win32gui.SetForegroundWindow(target_hwnd)
  272. except Exception as e:
  273. print(f"设置前台窗口时警告: {e}")
  274. print(f"窗口已置顶: {target_title}")
  275. return True
  276. except Exception as e:
  277. print(f"设置窗口置顶时出错: {e}")
  278. return False
  279. def yys_ocrAuto(positions):
  280. return ocrAuto('MuMu安卓设备', positions)
  281. def yys_dragAuto(positions, isQuick=False):
  282. return dragAuto('MuMu安卓设备', positions, isQuick)
  283. def getRegion(gamestr, region, isWidth):
  284. tmpRet, tmpPos = find_window_pos(gamestr)
  285. if tmpRet == False:
  286. return False
  287. if isWidth:
  288. return (region[0] + tmpPos[0], region[1] + tmpPos[1], region[2] - region[0], region[3] - region[1])
  289. else:
  290. return (region[0] + tmpPos[0], region[1] + tmpPos[1], region[2] + tmpPos[0], region[3] + tmpPos[1])
  291. def game_region():
  292. tmpRet, tmpPos = find_window_pos('MuMu安卓设备',)
  293. return tmpRet, tmpPos
  294. def save_game_screen(fileHeader=""):
  295. try:
  296. regionRet, regionPos = game_region()
  297. screenshot = pyautogui.screenshot(region=regionPos)
  298. curData = datetime.now().strftime("%Y_%m_%d_%H_%M_%S")
  299. fileName = "temp_pictures/" + fileHeader + "_" + curData + ".png"
  300. screenshot.save(fileName)
  301. return True
  302. except Exception as e:
  303. print(f"截图保存失败: {e}")
  304. return False
  305. # 创建并启动截图线程
  306. def start_screenshot_thread(fileHeader=""):
  307. screenshot_thread = threading.Thread(
  308. target=save_game_screen,
  309. args=(fileHeader,),
  310. name=f"ScreenshotThread_{fileHeader}"
  311. )
  312. screenshot_thread.start()
  313. return screenshot_thread
  314. def start_recording():
  315. global g_recorder
  316. regionRet, regionPos = game_region()
  317. print("record region,", regionPos)
  318. g_recorder.start_recording(regionPos)
  319. def stop_recording():
  320. global g_recorder
  321. g_recorder.stop_recording()
  322. def yys_getRegion(region, isWidth= False):
  323. return getRegion('MuMu安卓设备', region, isWidth)
  324. def click_waitimg(pos_x,pos_y,img):
  325. retry_times = 3
  326. while retry_times > 0 and waitFindImg_withBool(img,0.4,1) == False:
  327. pcacc_mouse.click(pos_x,pos_y)
  328. retry_times-=1
  329. return retry_times > 0
  330. if __name__ == '__main__':
  331. tryMoveTopWindow('MuMu安卓设备')