《找别扭》的窗口骇死我咧,Python鼠标不能直接够到它,又不能窗口化,只能使用《按键精灵》或在虚拟机里运行。Python部分:
import threading
import tkinter as tk
import random
import matplotlib
import win32gui
import win32con
matplotlib.use('TkAgg')
import matplotlib.pyplot as plt
import numpy as np
from PIL import Image, ImageTk, ImageChops
import pyautogui
from sklearn.cluster import KMeans
import time
x0, y0, x, W, H, border, image, imageTK = 16, 151, 386, 380, 292, 0, None, None
canvas, label = None, None
text = "按Space键计算"
def calculate():
global image, imageTK
diff = [] # 找出不同的点
img = pyautogui.screenshot()
background = img.crop((x0, y0, x0 + W, y0 + H))
img1 = img.crop((x0 + border, y0 + border, x0 + W - border, y0 + H - border)) # 截图当前活动窗口
img2 = img.crop((x0 + x + border, y0 + border, x0 + x + W - border, y0 + H - border))
sub = ImageChops.subtract(img1, img2)
imageTK = ImageTk.PhotoImage(sub)
image = canvas.create_image(0, 0, anchor="nw", image=imageTK)
for xi in range(W - 2 * border):
for yi in range(5, H - 2 * border):
pixel1, pixel2 = img1.getpixel((xi, yi)), img2.getpixel((xi, yi))
if max(abs(pixel1[0] - pixel2[0]), abs(pixel1[1] - pixel2[1]), abs(pixel1[2] - pixel2[2])) > 16:
row = [xi + border, H - 1 - yi + border]
if random.random() < 0.1:
diff.append(row)
diff = np.array(diff)
Solver = KMeans(n_clusters=5, n_init=20) # 把不同的点分成五类
Solver.fit(diff)
result = Solver.predict(diff)
C = Solver.cluster_centers_ # 质心、点击处
plt.cla()
plt.imshow(background.transpose(Image.FLIP_TOP_BOTTOM))
plt.scatter(diff[:, 0], diff[:, 1] - 2 * border, c="red", marker='s', s=20)
plt.scatter(diff[:, 0], diff[:, 1] - 2 * border, c=result, marker='s', s=10)
plt.scatter(C[:, 0], C[:, 1]-2*border, c="red", edgecolors='black', s=50)
plt.xlim(0, W)
plt.ylim(0, H)
plt.savefig(r'D:\录像/封面.png')
img = Image.open(r'D:\录像/封面.png')
imageTK = ImageTk.PhotoImage(img)
image = canvas.create_image(0, 0, anchor="nw", image=imageTK)
title = ''
print(C)
for c in C:
title += f'{int(x0 + border + c[0])}x{int(y0 + H - border - c[1])}y'
print(title)
window.title(title)
def onKeyDown(e):
global label, text
if e == "space": # 空格
text = "计算中"
label.config(text=text)
# test()
calculate()
text = "按Space键计算"
label.config(text=text)
# 你可以添加一些延迟来避免过高的CPU使用率
# 例如,使用 time.sleep(0.1) 来每100毫秒检查一次按键状态
return 0
def test(): # 校准
img = pyautogui.screenshot()
for dx in range(10, 30):
img1 = img.crop((x0 + border, y0 + border, x0 + W - border, y0 + H - border)) # 截图当前活动窗口
img2 = img.crop((x0 + x + dx + border, y0 + border, x0 + x + dx + W - border, y0 + H - border))
sub = ImageChops.subtract(img1, img2)
sub.save(fr"D:\录像\VipSongsDownload/x={x+dx}.jpg")
def thread():
global text
while True:
if window.title() != tk and text == "按Space键计算":
onKeyDown(window.title())
time.sleep(0.5)
window = tk.Tk()
window.focus_set() # 设置窗口焦点以接收按键事件
label = tk.Label(window, text=text)
label.pack()
canvas = tk.Canvas(window, bg='white', width=640, height=480)
canvas.pack()
# 创建一个Thread对象,target参数指定要在线程中运行的函数
second_thread = threading.Thread(target=thread)
second_thread.start() # 启动线程
window.mainloop() # 开始Tkinter的事件循环
将结果传递给按键精灵并执行的部分:
// 按键精灵端——收发消息和点击
tk = Plugin.Window.Find("TkTopLevel", "tk") // 抓取TK窗口的句柄
title = Plugin.Window.GetText(tk)
x0 = 400
y0 = 300
If title <> "space" Then
Call Plugin.Window.SetText(tk, "space")
While Plugin.Window.GetText(tk) = "space"
Wend
//当循环条件成立的时候,反复执行循环体
str = Plugin.Window.GetText(tk)
i = 1
x = 0
y = 0
res = ""
For Len(str)
c = Mid(str, i, 1)
If c="x" Then
x = CInt(res)
res = ""
ElseIf c="y" Then
y = CInt(res)
TracePrint (CStr(x) + " " + CStr(y))
MoveTo -3*x0, -3*y0
MoveTo x*2+x0, y*2+y0
LeftClick 1
Delay 200
x = 0
y = 0
res = ""
Else
res = res + c
End If
i = i+1
Next
Call Plugin.Window.SetText(tk, "tk")
End If
// 按键精灵端——将TK窗口置顶并放在屏幕2居中放置
Hwnd = Plugin.Window.Find("TkTopLevel", "tk")
Call Plugin.Window.Move(Hwnd, 800, 250)
Call Plugin.Window.Top(Hwnd, 0)
// 按键精灵端——进入下一关
x0 = 400
y0 = 300
MoveTo -3*x0, -3*y0
MoveTo 400*2+x0, 520*2+y0
LeftClick 1
// 按键精灵端——使用Joker
x0 = 400
y0 = 300
MoveTo -3*x0, -3*y0
MoveTo 300*2+x0, 120*2+y0
LeftClick 1