中等难度——python实现电子宠物和截图工具
import io # 文件处理
import nt # windows nt 库直接获取对应的磁盘空间
import time # 时间
import zlib # 加解密
import ctypes # 调用
import struct # 处理字节二进制
import base64 # 编解码
import threading # 线程
import tkinter as tk # tk
from datetime import datetime # 时间
from tkinter import PhotoImage, filedialog"""公用参数"""
gdi32 = ctypes.windll.gdi32
user32 = ctypes.windll.user32# 定义常量
SM_CXSCREEN = 0
SM_CYSCREEN = 1# 缩放比例
zoom = 1
screenWidth = int(user32.GetSystemMetrics(SM_CXSCREEN) * zoom)
screenHeight = int(user32.GetSystemMetrics(SM_CYSCREEN) * zoom)SRCCOPY = 0x00CC0020"""全局变量"""# 全屏截图
hdc_dest, old_bmp, hwnd, hdc_src, bmp = None, None, None, None, None
# 剪切图片
hdc_copy, old_bitmap, hbitmap = None, None, None
# 图片数据
image_data = None
# 像素数据
b_stream = None
# 绘画层
canvas = None
# 交互层
popup = None
# 全部层
root = None
# 判断跳出
times = None# 清理全部
def CleanScreen():global hdc_dest, old_bmp, hwnd, hdc_src, bmp, hdc_copy, old_bitmap, hbitmap# 恢复设备上下文gdi32.SelectObject(hdc_dest, old_bmp)gdi32.SelectObject(hdc_copy, old_bitmap)# 删除内存设备上下文gdi32.DeleteDC(hdc_dest)gdi32.DeleteDC(hdc_copy)# 释放桌面窗口的设备上下文user32.ReleaseDC(hwnd, hdc_src)# 处理位图gdi32.DeleteObject(bmp)gdi32.DeleteObject(hbitmap)hdc_dest, old_bmp, hwnd, hdc_src, bmp, hdc_copy, old_bitmap, hbitmap = None, None, None, None, None, None, None, None## gif动态
class GifPlayer:def __init__(self, root, label_widget):self.root = rootself.label_widget = label_widgetself.frames = []self.frame_index = 0self.update_delay = 300 # 毫秒p1 = "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"p2 = "iVBORw0KGgoAAAANSUhEUgAAAHMAAAAyCAYAAABvR+QvAAAJ10lEQVR4nO1b3VMTWRb/3U46CQRQjIjiF4L4seg4sg67W+W6W/OytY9bZVm+7j/mVmmVtVriy5Y6uusyCn4ySrGCED8AcdWBEBIg6XTS3ffsQ+i2Q3ffJISF6OT3Quhzz7mn+/Q9X/c2UEMNNdRQQw01fLEgG9LpNG22PjWsEclkkjRNKzCgYRiUyWSERh0fHyciqhm+muBlkFQqRUREly5dctA1TasZshpRzCim+00kEnZvXDMkAP9mK2DH4OAg3b17VziGMcY2SJ01Y3T8Icmyz5NORAiFQmjf+23V38uaYRjGV7HCHj66V/Q+Hjz+x7rfq7TeAiuBruubrcK6IBQKFR3Ttqtz3eetKmN+LSglhKtqet3nrSqfTURUzTHx5s3r1NvbA1AA5KJlKMiwuLiIVCqFyPY2VxkMOdTX12Nubg6BUBCyLAMUsNG59Turati950DVPg8hXr16RRcvXqzauBl99ZTu37+5YfqNjg3Qs+FbVfs8iiKVSlWt8tHo8Ibr9uTpDyXP6Vqa6LruKN1M72f+NQyj4P9K4ffnVVFVFURE65UM6boOwzAQDAateXK5HCQpny5wziHLMlRVRX19vfBmOGXWRadysLV5R8ljHcbUdZ38fv+X6acrRDXGbE3TSh7ryGZ9Pu9i92sH57z4oCqGsDRZcbcWkskkLS0tEQBks1lKp9MFdEVRLN9MRJTNZgt2Py5cuEAAoCiKdd1sopuN9BUXa9F1XSdd1y25nPOCOe2NBvv15eVlUhSFOOcEALlcjuLxeAGvXS4Ay/Wuxrv3zzYvjrP8ypyaGSmqg7Cdt7CwgB07dhS4HTOY6rqOcDhcQOvr67MmdHNXZpO8rq7OQTcfeiaTccSu27dvW3IlSXLInZiYoCNHjjBN0xAIBDz1jUQia3Khi4uLQvrHT+9odvYT6uqDaGrcirZdpZUT0zPjlM1mwRjDoYMnhDzpdPG6VGjMxsZGT1p9fb3jWjEXbSZN2WzWQTOvBQIBB215eVko14SZRNlhJlJ1dXUlybDj0dNb9LvePzPA2/0OPeuntl37CwzxMjpI2UwAJ7/tdTXQzMwEZbUk2vcdteizsUlKJOdxpMudR4IPL18+J4MrOH7stMcYAdwySlGWWSxYt7a2AoCVWdphLlS3F6JYLGtoaCiQYUclOcD27duF9P4f/0lbt0Yc14nL2BZp8ORbXEzgYEd3wbXWlg4WkMUvnCRJ1r26Qbgyo9Eo3r9/X+CrZVlmQN6Nvn79mux9SLuhV/NxzrF/f/4NHhoactBDoZAld3JykmRZBpD3DnYjreZLpVLYs2cPA4CBgQEHva+vD6bc4eFhMg0UDocRDAYdocKOYm25XW3b0dX5jYO/++hv2Fj0R/r71b/R+XN/LaDPx99SLqeDsUYHX0f7cfbhU5R27zrsqlNTUxPm4x889REa89SpU0I/3tXV5Unfu3evJ623192VmOjo6FiT3DNnzgjlnjx5sryYycxw4L66iQxP1oZwM86f+6NjPoKE+Xjck0/JpNzn4gCYBr/sPWet0S4CyULyNo+C/j8vhkjNuD/0lsgBZhgcj58MOJb92PgT6ur4tfcLRz6hTsKVuZL6i4ZYWF5eRjgctrJJwzDI7h7j8ThaWloYkC8TzGSFMYZ0Oo1wOAzGGFNVlTjnViKkKAoMw0Bzc7PFCwCyLINzDlVVcePGDZw7d46Vo68kSYjFYmhtbfV8eIc6fytcya079rH+gWt05PBxhAJb8ObtBLQcIbH4X/zh+F88eU+eOM3eTg9R9PUzik5M49R338DgKl5FJz3nYhJHW9vB8jyLvY+XSCTKqq+uXLkiHH/58mWrllxNM2s+N9r169eFckdHRz15y4EX/8hoPwHA+MRDV/rA4L8pnnhHPw3/i8bGn5asw8yHURqbeESvJ4coFp925RsdHyQAGJ3or6zO3Ei4lSvVglwuJ6T//vT3a6pf9+0+VjIfI+8y0YQwZrrVfCKI0mYg7xq9ICo/ijXd3erL9cR3PX/a9H5t91FxMgoUWZmxWAyzs7MluQ3GWEFNF4vFyNyhAPINg7a2NgYAU1NTllxVVREMBnH16lVTDhsdHaWWlhYA+RVrj71zc3OmSwWQf+HMeDo3N1eyvuFwGPPz82hvb990QwlRJAkT8/6Cjy0Wu3evmPn/RDkxuFaaVDnK2ckRutlkMklNTU0lCTIMA5qmWU1ys0wwXa9hGDD3STVNs0oTRVHAGAPnHA0NDSyXy9Hq2Mo5h8/ns3h9Pp/lenO5HILBIAOAdDpNpfZgdV2HLMtlncM1uIabP1yi/XsPgSRnCUS6GWY4mN99QTECTPtIzAfOAeY3CuhAvuW5lEpA8pW+nyk0pqZprrsUXrh37/N5UbeHdO3aNTp79izz+/0OejabNbeqHDsfDx48sOSa7UQ7xsbGqLu7mxmGUZa+5eJwVw+CgUYAHJycj04OhMEkA8vpOQTlLQCcLUEGoLm5EYlEApxL8MMPSLbVtzLeMAjh+mZkMuJM2g6hMd0a4iIU290QZZ1mse+2soqVBiZEuzzrAVl29lPd8Hy4nw4d6xGOHY/+REcPF89Qy4EwZopKCTekUu59xdXy3PIM88Vx2yBWFEUot5RDxxsKKm8RrBeEKzMUCpWc3aqqilAohPPnzwP4/KmByb5SulglhEk3jff8+XNzHFs5TWDJthtYVVUKBAKWXMMwCtxyqfrG43FEIpGKv115+PguxWKzOPqrQ/CzAOrCEt7PzJbE+2ZyhDg3EAgZAK9D+77SmwhuEBqzkhs1DeeGnTt3CuWK4p65VeaGzTiMFWneisi2LQgFgiDIyOUApYQ4F5S3wSfnx6npNDQjjo8f31DZ/Vcbqqad96WCkwbZ14B9e8tbVau3+cbG79PSUrIiXYrumrhdZ4w5SohMJlNwtmcjmw9uc65kxWYJwubn5ykS+XwqgIigKAoaGhoqWs2S5Ifo871SEZDry26frkaxOtNqlZkwD15JkuRwa/Zdk410eSMjI3TixAnrpIKdZhp4PeKjO7h1gq5yVNbD+So6QFV2bnnTIDSm20av2V5yOyhVqZtYK0rp+pSyxfalfx8qdLORSKQgDmUyGdy5cwdA3p0tLS2RvVBfWlqyfm9UzFxYWLDOw05NTTnmvXXrFoB8FmxvI5qo2PUyPX+cYz3g9p1gGXAY0/4GF7vRpqamqioTRAfBAPdWoB1r+TyhLhRGOp3Gzz9Pks+/tuYF5wrUjIbFZGUf4DqMmU6nMTU1RQcOfKEfea4RREQvXrwom0/NMMTnF+DzETjW5oxyaha65kNPj/vh5lLhyqzrOpkx8Wvf3sxmswgEApienkZnZ+cv6gWuoYYaaqihLPwPrYhAfjlO4DMAAAAASUVORK5CYII="p3 = "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"p4 = "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"p5 = p2p6 = "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"p7 = p2p8 = p2p9 = "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"p10 = "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"## 遍历图片list_name = ["p1", "p2", "p3", "p4", "p5", "p6", "p7", "p8", "p9", "p10"]list_str = [p1, p2, p3, p4, p5, p6, p7, p8, p9, p10]list_all = []for i in range(10):photo = tk.PhotoImage(name=list_name[i], data=base64.b64decode(list_str[i]))list_all.append(photo)# 获取所有帧self.frames = list_all# 初始化显示第一帧self.label_widget.config(image=self.frames[0])self.label_widget.image = self.frames[0]# 绑定拖动事件self.label_widget.bind("<ButtonPress-1>", self.on_press)self.label_widget.bind("<ButtonRelease-1>", self.on_button_release)# 开始动画self.play_gif()def play_gif(self):if self.frame_index < len(self.frames):self.label_widget.config(image=self.frames[self.frame_index])self.frame_index += 1self.root.after(self.update_delay, self.play_gif)else:self.frame_index = 0self.root.after(self.update_delay, self.play_gif)def on_press(self, event):# 记录鼠标按下时的位置self.start_x = event.xself.start_y = event.yself.initial_x = self.root.winfo_x()self.initial_y = self.root.winfo_y()def on_button_release(self, event):# 计算鼠标移动的距离delta_x = event.x - self.start_xdelta_y = event.y - self.start_y# 更新窗口位置self.root.geometry(f'+{self.initial_x + delta_x}+{self.initial_y + delta_y}')## 获取cpu和内存的使用率
class FILETIME(ctypes.Structure):_fields_ = [("dwLowDateTime", ctypes.c_ulong),("dwHighDateTime", ctypes.c_ulong)]class SYSTEMTIME(ctypes.Structure):_fields_ = [("wYear", ctypes.c_ushort),("wMonth", ctypes.c_ushort),("wDayOfWeek", ctypes.c_ushort),("wDay", ctypes.c_ushort),("wHour", ctypes.c_ushort),("wMinute", ctypes.c_ushort),("wSecond", ctypes.c_ushort),("wMilliseconds", ctypes.c_ushort)]class MEMORYSTATUSEX(ctypes.Structure):_fields_ = [("dwLength", ctypes.c_ulong),("dwMemoryLoad", ctypes.c_ulong),("ullTotalPhys", ctypes.c_ulonglong),("ullAvailPhys", ctypes.c_ulonglong),("ullTotalPageFile", ctypes.c_ulonglong),("ullAvailPageFile", ctypes.c_ulonglong),("ullTotalVirtual", ctypes.c_ulonglong),("ullAvailVirtual", ctypes.c_ulonglong),("ullAvailExtendedVirtual", ctypes.c_ulonglong)]## 调用dll
kernel32 = ctypes.windll.kernel32## 获取cpu使用率
def get_cpu_usage():def get_cpu_times():idle_time = FILETIME()kernel_time = FILETIME()user_time = FILETIME()kernel32.GetSystemTimes(ctypes.byref(idle_time), ctypes.byref(kernel_time), ctypes.byref(user_time))return (idle_time, kernel_time, user_time)def filetime_to_seconds(ft):return (ft.dwHighDateTime * 0x100000000 + ft.dwLowDateTime) / 1e7(idle1, kernel1, user1) = get_cpu_times()time.sleep(1)(idle2, kernel2, user2) = get_cpu_times()idle_diff = filetime_to_seconds(idle2) - filetime_to_seconds(idle1)system_diff = (filetime_to_seconds(kernel2) - filetime_to_seconds(kernel1)) + \(filetime_to_seconds(user2) - filetime_to_seconds(user1))return float("{:.1f}".format((1.0 - idle_diff / system_diff) * 100.0))## 获取内存使用率
def get_memory_usage():mem_info = MEMORYSTATUSEX()mem_info.dwLength = ctypes.sizeof(MEMORYSTATUSEX)kernel32.GlobalMemoryStatusEx(ctypes.byref(mem_info))return float(mem_info.dwMemoryLoad)## 启动tk的gui
def main():top = tk.Tk()top.title("GIF 动画播放器")top.overrideredirect(True) # 无边框bg_color = '#FFFFF1'top.config(bg=bg_color) # 背景色top.wm_attributes('-transparentcolor', bg_color)top.wm_attributes("-topmost", True) # 窗口置顶top.attributes('-alpha', 1) # 设置透明度,0.0 完全透明,1.0 完全不透明# 获取屏幕宽度和高度screen_width = top.winfo_screenwidth()screen_height = top.winfo_screenheight()# 窗口大小为300x200window_width = 300window_height = 200# 计算窗口位置,使其出现在右下角x_position = screen_width - window_widthy_position = screen_height - window_height# 设置窗口的初始位置和大小top.geometry(f'{window_width}x{window_height}+{int(x_position)}+{int(y_position)}')# 创建Label来显示GIFlabel = tk.Label(top, bg=bg_color)label.pack(expand=True, fill='both') # 确保Label填充整个窗口# 初始化GifPlayerGifPlayer(top, label)# 显示时间的Labeltime_label = tk.Label(top, bg=bg_color, fg='white', font=('Arial', 12))time_label.place(x=window_width // 2 - 50, y=50)## 更新时间def update_time():# 获取当前时间并格式化为 时:分:秒current_time = datetime.now().strftime('%H:%M:%S')# 更新时间标签的文本time_label.config(text=current_time)# 每秒调用一次自己以更新时间top.after(1000, update_time)update_time()## 状态显示status_show = tk.Label(top, bg=bg_color, fg='white', font=('Arial', 10))status_show.place(x=window_width // 2 + 60, y=55)## 更新状态def update_status_show():def update_status():## 状态更新cpu_status = get_cpu_usage()memory_status = get_memory_usage()total, free = nt._getdiskusage('C:/')disk_status = free / (2 ** 30)## 颜表情表现list_emote = ["(^▽^)", "(⊙_⊙)", "(一_一)", "(一_一)!", "(╥_╥)"]if 0 <= cpu_status < 20:string_status = list_emote[0]elif 20 <= cpu_status < 40:string_status = list_emote[1]elif 40 <= cpu_status < 60:string_status = list_emote[2]elif 60 <= cpu_status < 80:string_status = list_emote[3]elif 80 <= cpu_status <= 100:string_status = list_emote[4]status_text = "CPU:{0:.1f}%\n内存:{1:.1f}%\n磁盘C:{2:.1f}G\n{3}\n".format(cpu_status, memory_status,disk_status, string_status)# 更新文本status_show.config(text=status_text)status_thread = threading.Thread(target=update_status)# 启动线程status_thread.start()# 自调用更新top.after(2000, update_status_show)## 状态更新update_status_show()## 点击处理def on_button_click():def screenshot():"""常用函数"""# 销毁共用组件def destroy():global canvas, popup, rootif canvas:canvas.destroy()if popup:popup.destroy()if root:root.destroy()"""实现函数"""# 全屏截图def Full_screen_capture(x, y, width, height):global hdc_dest, old_bmp, hwnd, hdc_src, bmp# 获取桌面窗口句柄hwnd = user32.GetDesktopWindow()# 获取桌面窗口的设备上下文hdc_src = user32.GetDC(hwnd)if len(str(hdc_src)) > 16:user32.ReleaseDC(hwnd, hdc_src)print("获取失败")returnprint(hwnd)print(hdc_src)# 创建一个与屏幕兼容的内存设备上下文hdc_dest = gdi32.CreateCompatibleDC(hdc_src)# 创建一个位图bmp = gdi32.CreateCompatibleBitmap(hdc_src, width, height)# 将位图选入内存设备上下文old_bmp = gdi32.SelectObject(hdc_dest, bmp)"""gdi32.BitBlt(hdc_src, # 目标设备上下文 x_dest, # 目标矩形左上角的x坐标 y_dest, # 目标矩形左上角的y坐标 width, # 宽度 height, # 高度 hdc_dest, # 源设备上下文 x_src, # 源矩形左上角的x坐标(通常是0) y_src, # 源矩形左上角的y坐标(通常是0) SRCCOPY) # 复制选项"""# 捕获屏幕gdi32.BitBlt(hdc_dest, 0, 0, width, height, hdc_src, x, y, SRCCOPY)# 制作图片def png_image(width, height):global image_data, hdc_src, bmp, b_streamif len(str(hdc_src)) > 16:user32.ReleaseDC(hwnd, hdc_src)print("获取失败")return# 定义 RGBQUAD 结构体class RGBQUAD(ctypes.Structure):_fields_ = [("rgbBlue", ctypes.c_ubyte),("rgbGreen", ctypes.c_ubyte),("rgbRed", ctypes.c_ubyte),("rgbReserved", ctypes.c_ubyte)]# 定义 BITMAPINFOHEADER 结构体class BITMAPINFOHEADER(ctypes.Structure):_fields_ = [("biSize", ctypes.c_uint),("biWidth", ctypes.c_int),("biHeight", ctypes.c_int),("biPlanes", ctypes.c_ushort),("biBitCount", ctypes.c_ushort),("biCompression", ctypes.c_uint),("biSizeImage", ctypes.c_uint),("biXPelsPerMeter", ctypes.c_int),("biYPelsPerMeter", ctypes.c_int),("biClrUsed", ctypes.c_uint),("biClrImportant", ctypes.c_uint)]# 定义 BITMAPINFO 结构体class BITMAPINFO(ctypes.Structure):_fields_ = [("bmiHeader", BITMAPINFOHEADER),("bmiColors", RGBQUAD * 3)] # 只分配了3个RGBQUAD的空间BI_RGB = 0DIB_RGB_COLORS = 0# 分配像素数据缓冲区(这里以24位位图为例,每个像素3字节)pixel_data = (ctypes.c_ubyte * (width * height * 3))() # 4# 转换bytes# pixel_data = memoryview(pixel_data).tobytes()# 填充 BITMAPINFO 结构体bmi = BITMAPINFO()bmi.bmiHeader.biSize = ctypes.sizeof(BITMAPINFOHEADER)bmi.bmiHeader.biWidth = widthbmi.bmiHeader.biHeight = -height # 注意:负高度表示自底向上的位图bmi.bmiHeader.biPlanes = 1bmi.bmiHeader.biBitCount = 24 # 24即3*8 32bmi.bmiHeader.biCompression = BI_RGB # 无压缩# 调用 GetDIBits 获取像素数据ret = gdi32.GetDIBits(hdc_src, bmp, 0, height, pixel_data, ctypes.byref(bmi), DIB_RGB_COLORS)if ret == 0:print("GetDIBits failed:", ctypes.WinError())# 像素色彩换位置mv = (memoryview(pixel_data).cast('B'))# b_stream = bytearray(width * (height+1) * 3)print(len(mv))b_stream = bytearray()k = 0# for i in range(0, len(mv), 3):# if i % (width*3) == 0:# # b_stream[k] = 0# k += 1# b_stream[k] = mv[i + 2]# b_stream[k + 1] = mv[i + 1]# b_stream[k + 2] = mv[i]# k+=3for i in range(0, len(mv), 3): # 4if i % (width * 3) == 0:b_stream.append(0)k += 1b_stream.append(mv[i + 2])b_stream.append(mv[i + 1])b_stream.append(mv[i])# b_stream.extend([mv[i + 2],mv[i + 1],mv[i]])k += 3# b_stream.append(mv[i+2])# b_stream.append(mv[i+1])# b_stream.append(mv[i+0])# b_stream.append(mv[i+3])# k+=4# print(b_stream)def crc32(data): # 字节流crc = zlib.crc32(data)return crcdef crc32_b(data):crc = zlib.crc32(data).to_bytes(4, byteorder='big')return crc# png图片标识符png_signature = b"\x89PNG\r\n\x1a\n"# IHDR块ihdr = struct.pack("!IIBBBBB", width, height, 8, 2, 0, 0, 0) # 8 6 0 0 0# IHDR的CRC验证mid = crc32_b(b"IHDR" + ihdr)# 压缩图片数据bd = zlib.compress(bytes(b_stream))# IDAT的CRC验证crc_bytes = crc32_b(b"IDAT" + bd)idat_chunk = b"IDAT" + bd + crc_bytes# IEND块iend = b"\x00\x00\x00\x00IEND"# IEND的CRC验证crc_end = crc32_b(b"IEND")iend += crc_end# 写入图片操作,使用BytesIO来构建PNGpng_io = io.BytesIO()png_io.write(png_signature + b"\x00\x00\x00\rIHDR" + ihdr + mid)idat_header = struct.pack("!I", len(bd))png_io.write(idat_header + idat_chunk)png_io.write(iend)image_data = png_io.getvalue()# 剪切图片def Cut_png_image(x1, x2, y1, y2):global b_stream, image_dataprint(screenWidth, screenHeight)x = abs(x1 - x2)y = abs(y1 - y2)min_x = min(x1, x2)min_y = min(y1, y2)one_line_pixel = screenWidth * 3 + 1cut_stream = bytearray()for i in range(1, screenHeight + 1):if i >= min_y and i < min_y + y:cut_stream.append(0)cut_stream.extend(b_stream[one_line_pixel * (i - 1) + (min_x - 1) * 3 + 1:one_line_pixel * (i - 1) + (min_x + x) * 3 - 2])def crc32(data): # 字节流crc = zlib.crc32(data)return crcdef crc32_b(data):crc = zlib.crc32(data).to_bytes(4, byteorder='big')return crc# png图片标识符png_signature = b"\x89PNG\r\n\x1a\n"# IHDR块ihdr = struct.pack("!IIBBBBB", x, y, 8, 2, 0, 0, 0) # 8 6 0 0 0# IHDR的CRC验证mid = crc32_b(b"IHDR" + ihdr)# 压缩图片数据bd = zlib.compress(bytes(cut_stream))# IDAT的CRC验证crc_bytes = crc32_b(b"IDAT" + bd)idat_chunk = b"IDAT" + bd + crc_bytes# IEND块iend = b"\x00\x00\x00\x00IEND"# IEND的CRC验证crc_end = crc32_b(b"IEND")iend += crc_end# 写入图片操作,使用BytesIO来构建PNGpng_io = io.BytesIO()png_io.write(png_signature + b"\x00\x00\x00\rIHDR" + ihdr + mid)idat_header = struct.pack("!I", len(bd))png_io.write(idat_header + idat_chunk)png_io.write(iend)image_data = png_io.getvalue()# 剪切def Cut(x, y, width, height):global hdc_copy, hbitmap, old_bitmap,hdc_src,hdc_dest# 设置裁剪区域x_clip, y_clip, width_clip, height_clip = x, y, width, height # 裁剪区域的坐标和尺寸# 创建一个与屏幕兼容的内存设备上下文hdc_copy = gdi32.CreateCompatibleDC(hdc_src)# 创建对应大小位图hbitmap = gdi32.CreateCompatibleBitmap(hdc_src, width_clip, height_clip) # 创建大小为裁剪区域尺寸的兼容位图old_bitmap = gdi32.SelectObject(hdc_copy, hbitmap) # 将位图选入兼容设备上下文# 传递gdi32.BitBlt(hdc_copy, 0, 0, width_clip, height_clip, hdc_dest, x_clip, y_clip, SRCCOPY)# 复制def copy_bmp():global hbitmap# 这里是复制bmp图片内存对象# 加载必要的 Windows API 函数user32_1 = ctypes.windll.user32kernel32_1 = ctypes.windll.kernel32# 定义常量CF_BITMAP = 2# 打开剪贴板def OpenClipboard(hwnd):return user32_1.OpenClipboard(hwnd)# 关闭剪贴板def CloseClipboard():return user32_1.CloseClipboard()# 清空剪贴板def EmptyClipboard():return user32_1.EmptyClipboard()# 设置剪贴板数据def SetClipboardData(uFormat, hData):return user32_1.SetClipboardData(uFormat, hData)# 获取剪切板数据def GetClipboardData(uFormat):return user32_1.GetClipboardData(uFormat)# 全局分配内存def GlobalAlloc(uFlags, dwBytes):return kernel32_1.GlobalAlloc(uFlags, dwBytes)# 全局锁定内存def GlobalLock(hMem):return kernel32_1.GlobalLock(hMem)# 全局解锁内存def GlobalUnlock(hMem):return kernel32_1.GlobalUnlock(hMem)# 将图片复制到剪贴板def copy_bmp_to_clipboard():hwnd = 0if OpenClipboard(hwnd):try:EmptyClipboard()SetClipboardData(CF_BITMAP, hbitmap) # CF_BITMAP = 2finally:passCloseClipboard()# 复制copy_bmp_to_clipboard()"""绘画层"""class DrawingApp:def __init__(self):global popup, canvas, root, image_data# 初始化主窗口root = tk.Toplevel(top)# root.overrideredirect(True)bg_color = '#F0F0F0'root.config(bg=bg_color) # 背景色root.wm_attributes('-transparentcolor', bg_color)# 设置窗口为全屏模式root.attributes('-fullscreen', True)root.wm_attributes("-topmost", True) # 窗口置顶photo = PhotoImage(data=image_data)print(photo)# 创建Canvas用于传递canvas = tk.Canvas(root, width=screenWidth, height=screenHeight)self.root = rootself.root.wm_attributes("-topmost", True) # 窗口置顶self.root.attributes('-fullscreen', True) # 全屏self.canvas = canvasself.canvas.pack(expand=True)self.canvas.config(highlightthickness=0) # 设置canvas边框为0self.canvas.create_image(0, 0, image=photo, anchor=tk.NW)self.canvas.image = photoi1 = "iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAIAAAC0Ujn1AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAAEnQAABJ0Ad5mH3gAAABTSURBVEhL7cxBCgAhDENRb+7Rq0gWNqKUDrPRvFUR84v9Rmni0jUF4wWncYW9k+53AsbDKY0rTGmiNFGaXJme4TWMJi49U5r0fwkYD9v0d0o7Zg0Izd58BueWAwAAAABJRU5ErkJggg=="i2 = "iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAIAAAC0Ujn1AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAAEnQAABJ0Ad5mH3gAAACSSURBVEhL7ZbRDoAgCEWt9d/65+aClQgqczpndV7EhXc3YNPNe2/GsOM6gDWln1o75yBoQD4bpAFrLUY05vCvYn63gnDjfaSDLoD7izUn5MCVkfxdC9jO2lRoSBTWrPWMNgaqnSwnZF1rJqScI7uGMxrXAO4pk2oNiKZyTmMapTW8b66Bj9W6z41+E4v8DzOCMSddJdqD9ODtiwAAAABJRU5ErkJggg=="i3 = "iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAIAAAC0Ujn1AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAAEnQAABJ0Ad5mH3gAAAC3SURBVEhL3ZFBDsIwEAP5OU8vlna1pMHxupFAwJzaejI59Ha8jT9O31/IQaLSmWGhHOQdy7Q+VgiNp81usJJJ+lI3oEfmdEnmBcI/pae5rWtfpYGot3KTBtsfn2lqB9NkmlYa1GpqwE0DCI6TT1+RrtXUwEd+I6Bntj82aZoIWlmlRTfQ/ikNam67gfDnNDCjI/QISYNL9ZXM08CsC22ZBjgW5PtADvJ6lS4yM5CDxErv8Yvp43gAlXf3/IGNU4IAAAAASUVORK5CYII="i4 = "iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAIAAAC0Ujn1AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAABxSURBVEhL7ZZLDoAwCETRi8PNkSjxMyXRWlmY8DZlM29BmgyTqlIOs78JJKpxISLiUydB0NQ7zOxTP5aF+KEe8W6A4ctd207Oa/nnDyk1UGqg1ECpgVIj3jYrgx12U2BBMT8D2ssIrqd39jZVh9kFogUN7BwohR5/ywAAAABJRU5ErkJggg=="self.image1 = PhotoImage(data=base64.b64decode(i1))self.image2 = PhotoImage(data=base64.b64decode(i2))self.image3 = PhotoImage(data=base64.b64decode(i3))self.image4 = PhotoImage(data=base64.b64decode(i4))self.rect_id = Noneself.start_x = Noneself.start_y = Noneself.bind_events()def bind_events(self):self.canvas.bind("<ButtonPress-1>", self.on_button_press)self.canvas.bind("<B1-Motion>", self.on_mouse_drag)self.canvas.bind("<ButtonRelease-1>", self.on_button_release)self.canvas.bind("<Button-3>", self.on_right_click) # 鼠标右键def on_button_press(self, event):self.start_x = event.xself.start_y = event.yif popup:popup.destroy()## 右键点击销毁def on_right_click(self, event):destroy()global timestimes = 1def on_mouse_drag(self, event):if self.rect_id:self.canvas.delete(self.rect_id)self.rect_id = self.canvas.create_rectangle(self.start_x, self.start_y, event.x, event.y,outline='red',width=2)if popup:popup.destroy()def on_button_release(self, event):if self.rect_id:self.canvas.delete(self.rect_id)self.rect_id = self.canvas.create_rectangle(self.start_x, self.start_y, event.x, event.y,outline='red',width=2, fill='')"""交互层"""def copy_photo():x = min(self.start_x, event.x)y = min(self.start_y, event.y)width = abs(self.start_x - event.x)higth = abs(self.start_y - event.y)Cut(x, y, width, higth)copy_bmp()destroy()global timestimes = 1def save_photo():file_path = filedialog.asksaveasfilename(initialfile=datetime.now().strftime("%Y-%m-%d-%H-%M-%S"),defaultextension=".png",filetypes=[("PNG files", "*.png"), ("JPEG files", "*.jpg"),("All files", "*.*")])if file_path:Cut_png_image(self.start_x, event.x, self.start_y, event.y)with open(file_path, "wb") as f:f.write(image_data)destroy()global timestimes = 1def close_popup():destroy()global timestimes = 1def all_popup():file_path = filedialog.asksaveasfilename(initialfile=datetime.now().strftime("%Y-%m-%d-%H-%M-%S"),defaultextension=".png",filetypes=[("PNG files", "*.png"), ("JPEG files", "*.jpg"),("All files", "*.*")])if file_path:with open(file_path, "wb") as f:f.write(image_data)destroy()global timestimes = 1global popup# 弹出窗口bg_color = '#FFFFF1'popup = tk.Toplevel(self.root)popup.title("操作选项")popup.geometry("+" + str(event.x) + "+" + str(event.y))popup.wm_attributes("-topmost", True)popup.config(bg=bg_color) # 背景色popup.wm_attributes('-transparentcolor', bg_color) # 窗口色popup.overrideredirect(True) # 无边框tk.Button(popup, image=self.image1, text="复制", command=copy_photo).grid(row=0, column=0, padx=0,pady=0)tk.Button(popup, image=self.image2, text="保存", command=save_photo).grid(row=0, column=1, padx=0,pady=0)tk.Button(popup, image=self.image3, text="关闭", command=close_popup).grid(row=0, column=3, padx=0,pady=0)tk.Button(popup, image=self.image4, text="全部", command=all_popup).grid(row=0, column=2, padx=0,pady=0)"""启动层"""global timestimes = NoneFull_screen_capture(0, 0, screenWidth, screenHeight)png_image(screenWidth, screenHeight)if not len(str(hdc_src)) > 16:DrawingApp()# 百秒内截图处理time_end = 100for t in range(time_end):if times != None:CleanScreen()breakelse:time.sleep(1)if t == time_end-1:destroy()CleanScreen()print("释放内存")global rootroot = Nonepassstatus_thread = threading.Thread(target=screenshot)# 启动线程status_thread.start()# 创建按钮,并绑定事件处理函数button = tk.Button(top, text="截图", command=on_button_click, bg=bg_color, fg="#FFFFFF")button.place(x=window_width // 2 + 80, y=25)# 按键监控def key_state():global rootkey = 0x72 # F3prev_state = 0while True:time.sleep(0.02)# 获取按键状态state = user32.GetAsyncKeyState(key)if state & 0x8000:if not prev_state & 0x8000 and root == None:print("F3 键被按下")on_button_click()# elif prev_state & 0x8000:# print("F3 键被释放")prev_state = statekey_thread = threading.Thread(target=key_state)# 启动线程key_thread.start()top.mainloop()if __name__ == "__main__":main()
import io # 文件处理
import nt # windows nt 库直接获取对应的磁盘空间
import time # 时间
import zlib # 加解密
import ctypes # 调用
import struct # 处理字节二进制
import base64 # 编解码
import threading # 线程
import tkinter as tk # tk
from datetime import datetime # 时间
from tkinter import PhotoImage, filedialog"""公用参数"""
gdi32 = ctypes.windll.gdi32
user32 = ctypes.windll.user32# 定义常量
SM_CXSCREEN = 0
SM_CYSCREEN = 1# 缩放比例
zoom = 1
screenWidth = int(user32.GetSystemMetrics(SM_CXSCREEN) * zoom)
screenHeight = int(user32.GetSystemMetrics(SM_CYSCREEN) * zoom)SRCCOPY = 0x00CC0020"""全局变量"""# 全屏截图
hdc_dest, old_bmp, hwnd, hdc_src, bmp = None, None, None, None, None
# 剪切图片
hdc_copy, old_bitmap, hbitmap = None, None, None
# 图片数据
image_data = None
# 像素数据
b_stream = None
# 绘画层
canvas = None
# 交互层
popup = None
# 全部层
root = None
# 判断跳出
times = None# 清理全部
def CleanScreen():global hdc_dest, old_bmp, hwnd, hdc_src, bmp, hdc_copy, old_bitmap, hbitmap# 恢复设备上下文gdi32.SelectObject(hdc_dest, old_bmp)gdi32.SelectObject(hdc_copy, old_bitmap)# 删除内存设备上下文gdi32.DeleteDC(hdc_dest)gdi32.DeleteDC(hdc_copy)# 释放桌面窗口的设备上下文user32.ReleaseDC(hwnd, hdc_src)# 处理位图gdi32.DeleteObject(bmp)gdi32.DeleteObject(hbitmap)hdc_dest, old_bmp, hwnd, hdc_src, bmp, hdc_copy, old_bitmap, hbitmap = None, None, None, None, None, None, None, None## gif动态
class GifPlayer:def __init__(self, root, label_widget):self.root = rootself.label_widget = label_widgetself.frames = []self.frame_index = 0self.update_delay = 300 # 毫秒p1 = "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"p2 = "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"p3 = "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"p4 = "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"p5 = p2p6 = "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"p7 = p2p8 = p2p9 = "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"p10 = "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"## 遍历图片list_name = ["p1", "p2", "p3", "p4", "p5", "p6", "p7", "p8", "p9", "p10"]list_str = [p1, p2, p3, p4, p5, p6, p7, p8, p9, p10]list_all = []for i in range(10):photo = tk.PhotoImage(name=list_name[i], data=base64.b64decode(list_str[i]))list_all.append(photo)# 获取所有帧self.frames = list_all# 初始化显示第一帧self.label_widget.config(image=self.frames[0])self.label_widget.image = self.frames[0]# 绑定拖动事件self.label_widget.bind("<ButtonPress-1>", self.on_press)self.label_widget.bind("<ButtonRelease-1>", self.on_button_release)# 开始动画self.play_gif()def play_gif(self):if self.frame_index < len(self.frames):self.label_widget.config(image=self.frames[self.frame_index])self.frame_index += 1self.root.after(self.update_delay, self.play_gif)else:self.frame_index = 0self.root.after(self.update_delay, self.play_gif)def on_press(self, event):# 记录鼠标按下时的位置self.start_x = event.xself.start_y = event.yself.initial_x = self.root.winfo_x()self.initial_y = self.root.winfo_y()def on_button_release(self, event):# 计算鼠标移动的距离delta_x = event.x - self.start_xdelta_y = event.y - self.start_y# 更新窗口位置self.root.geometry(f'+{self.initial_x + delta_x}+{self.initial_y + delta_y}')## 获取cpu和内存的使用率
class FILETIME(ctypes.Structure):_fields_ = [("dwLowDateTime", ctypes.c_ulong),("dwHighDateTime", ctypes.c_ulong)]class SYSTEMTIME(ctypes.Structure):_fields_ = [("wYear", ctypes.c_ushort),("wMonth", ctypes.c_ushort),("wDayOfWeek", ctypes.c_ushort),("wDay", ctypes.c_ushort),("wHour", ctypes.c_ushort),("wMinute", ctypes.c_ushort),("wSecond", ctypes.c_ushort),("wMilliseconds", ctypes.c_ushort)]class MEMORYSTATUSEX(ctypes.Structure):_fields_ = [("dwLength", ctypes.c_ulong),("dwMemoryLoad", ctypes.c_ulong),("ullTotalPhys", ctypes.c_ulonglong),("ullAvailPhys", ctypes.c_ulonglong),("ullTotalPageFile", ctypes.c_ulonglong),("ullAvailPageFile", ctypes.c_ulonglong),("ullTotalVirtual", ctypes.c_ulonglong),("ullAvailVirtual", ctypes.c_ulonglong),("ullAvailExtendedVirtual", ctypes.c_ulonglong)]## 调用dll
kernel32 = ctypes.windll.kernel32## 获取cpu使用率
def get_cpu_usage():def get_cpu_times():idle_time = FILETIME()kernel_time = FILETIME()user_time = FILETIME()kernel32.GetSystemTimes(ctypes.byref(idle_time), ctypes.byref(kernel_time), ctypes.byref(user_time))return (idle_time, kernel_time, user_time)def filetime_to_seconds(ft):return (ft.dwHighDateTime * 0x100000000 + ft.dwLowDateTime) / 1e7(idle1, kernel1, user1) = get_cpu_times()time.sleep(1)(idle2, kernel2, user2) = get_cpu_times()idle_diff = filetime_to_seconds(idle2) - filetime_to_seconds(idle1)system_diff = (filetime_to_seconds(kernel2) - filetime_to_seconds(kernel1)) + \(filetime_to_seconds(user2) - filetime_to_seconds(user1))return float("{:.1f}".format((1.0 - idle_diff / system_diff) * 100.0))## 获取内存使用率
def get_memory_usage():mem_info = MEMORYSTATUSEX()mem_info.dwLength = ctypes.sizeof(MEMORYSTATUSEX)kernel32.GlobalMemoryStatusEx(ctypes.byref(mem_info))return float(mem_info.dwMemoryLoad)## 启动tk的gui
def main():top = tk.Tk()top.title("GIF 动画播放器")top.overrideredirect(True) # 无边框bg_color = '#FFFFF1'top.config(bg=bg_color) # 背景色top.wm_attributes('-transparentcolor', bg_color)top.wm_attributes("-topmost", True) # 窗口置顶top.attributes('-alpha', 1) # 设置透明度,0.0 完全透明,1.0 完全不透明# 获取屏幕宽度和高度screen_width = top.winfo_screenwidth()screen_height = top.winfo_screenheight()# 窗口大小为300x200window_width = 300window_height = 200# 计算窗口位置,使其出现在右下角x_position = screen_width - window_widthy_position = screen_height - window_height# 设置窗口的初始位置和大小top.geometry(f'{window_width}x{window_height}+{int(x_position)}+{int(y_position)}')# 创建Label来显示GIFlabel = tk.Label(top, bg=bg_color)label.pack(expand=True, fill='both') # 确保Label填充整个窗口# 初始化GifPlayerGifPlayer(top, label)# 显示时间的Labeltime_label = tk.Label(top, bg=bg_color, fg='white', font=('Arial', 12))time_label.place(x=window_width // 2 - 50, y=50)## 更新时间def update_time():# 获取当前时间并格式化为 时:分:秒current_time = datetime.now().strftime('%H:%M:%S')# 更新时间标签的文本time_label.config(text=current_time)# 每秒调用一次自己以更新时间top.after(1000, update_time)update_time()## 状态显示status_show = tk.Label(top, bg=bg_color, fg='white', font=('Arial', 10))status_show.place(x=window_width // 2 + 60, y=55)## 更新状态def update_status_show():def update_status():## 状态更新cpu_status = get_cpu_usage()memory_status = get_memory_usage()total, free = nt._getdiskusage('C:/')disk_status = free / (2 ** 30)## 颜表情表现list_emote = ["(^▽^)", "(⊙_⊙)", "(一_一)", "(一_一)!", "(╥_╥)"]if 0 <= cpu_status < 20:string_status = list_emote[0]elif 20 <= cpu_status < 40:string_status = list_emote[1]elif 40 <= cpu_status < 60:string_status = list_emote[2]elif 60 <= cpu_status < 80:string_status = list_emote[3]elif 80 <= cpu_status <= 100:string_status = list_emote[4]status_text = "CPU:{0:.1f}%\n内存:{1:.1f}%\n磁盘C:{2:.1f}G\n{3}\n".format(cpu_status, memory_status,disk_status, string_status)# 更新文本status_show.config(text=status_text)status_thread = threading.Thread(target=update_status)# 启动线程status_thread.start()# 自调用更新top.after(2000, update_status_show)## 状态更新update_status_show()## 点击处理def on_button_click():def screenshot():"""常用函数"""# 销毁共用组件def destroy():global canvas, popup, rootif canvas:canvas.destroy()if popup:popup.destroy()if root:root.destroy()"""实现函数"""# 全屏截图def Full_screen_capture(x, y, width, height):global hdc_dest, old_bmp, hwnd, hdc_src, bmp# 获取桌面窗口句柄hwnd = user32.GetDesktopWindow()# 获取桌面窗口的设备上下文hdc_src = user32.GetDC(hwnd)if len(str(hdc_src)) > 16:user32.ReleaseDC(hwnd, hdc_src)print("获取失败")returnprint(hwnd)print(hdc_src)# 创建一个与屏幕兼容的内存设备上下文hdc_dest = gdi32.CreateCompatibleDC(hdc_src)# 创建一个位图bmp = gdi32.CreateCompatibleBitmap(hdc_src, width, height)# 将位图选入内存设备上下文old_bmp = gdi32.SelectObject(hdc_dest, bmp)"""gdi32.BitBlt(hdc_src, # 目标设备上下文 x_dest, # 目标矩形左上角的x坐标 y_dest, # 目标矩形左上角的y坐标 width, # 宽度 height, # 高度 hdc_dest, # 源设备上下文 x_src, # 源矩形左上角的x坐标(通常是0) y_src, # 源矩形左上角的y坐标(通常是0) SRCCOPY) # 复制选项"""# 捕获屏幕gdi32.BitBlt(hdc_dest, 0, 0, width, height, hdc_src, x, y, SRCCOPY)# 制作图片def png_image(width, height):global image_data, hdc_src, bmp, b_streamif len(str(hdc_src)) > 16:user32.ReleaseDC(hwnd, hdc_src)print("获取失败")return# 定义 RGBQUAD 结构体class RGBQUAD(ctypes.Structure):_fields_ = [("rgbBlue", ctypes.c_ubyte),("rgbGreen", ctypes.c_ubyte),("rgbRed", ctypes.c_ubyte),("rgbReserved", ctypes.c_ubyte)]# 定义 BITMAPINFOHEADER 结构体class BITMAPINFOHEADER(ctypes.Structure):_fields_ = [("biSize", ctypes.c_uint),("biWidth", ctypes.c_int),("biHeight", ctypes.c_int),("biPlanes", ctypes.c_ushort),("biBitCount", ctypes.c_ushort),("biCompression", ctypes.c_uint),("biSizeImage", ctypes.c_uint),("biXPelsPerMeter", ctypes.c_int),("biYPelsPerMeter", ctypes.c_int),("biClrUsed", ctypes.c_uint),("biClrImportant", ctypes.c_uint)]# 定义 BITMAPINFO 结构体class BITMAPINFO(ctypes.Structure):_fields_ = [("bmiHeader", BITMAPINFOHEADER),("bmiColors", RGBQUAD * 3)] # 只分配了3个RGBQUAD的空间BI_RGB = 0DIB_RGB_COLORS = 0# 分配像素数据缓冲区(这里以24位位图为例,每个像素3字节)pixel_data = (ctypes.c_ubyte * (width * height * 3))() # 4# 转换bytes# pixel_data = memoryview(pixel_data).tobytes()# 填充 BITMAPINFO 结构体bmi = BITMAPINFO()bmi.bmiHeader.biSize = ctypes.sizeof(BITMAPINFOHEADER)bmi.bmiHeader.biWidth = widthbmi.bmiHeader.biHeight = -height # 注意:负高度表示自底向上的位图bmi.bmiHeader.biPlanes = 1bmi.bmiHeader.biBitCount = 24 # 24即3*8 32bmi.bmiHeader.biCompression = BI_RGB # 无压缩# 调用 GetDIBits 获取像素数据ret = gdi32.GetDIBits(hdc_src, bmp, 0, height, pixel_data, ctypes.byref(bmi), DIB_RGB_COLORS)if ret == 0:print("GetDIBits failed:", ctypes.WinError())# 像素色彩换位置mv = (memoryview(pixel_data).cast('B'))# b_stream = bytearray(width * (height+1) * 3)print(len(mv))b_stream = bytearray()k = 0# for i in range(0, len(mv), 3):# if i % (width*3) == 0:# # b_stream[k] = 0# k += 1# b_stream[k] = mv[i + 2]# b_stream[k + 1] = mv[i + 1]# b_stream[k + 2] = mv[i]# k+=3for i in range(0, len(mv), 3): # 4if i % (width * 3) == 0:b_stream.append(0)k += 1b_stream.append(mv[i + 2])b_stream.append(mv[i + 1])b_stream.append(mv[i])# b_stream.extend([mv[i + 2],mv[i + 1],mv[i]])k += 3# b_stream.append(mv[i+2])# b_stream.append(mv[i+1])# b_stream.append(mv[i+0])# b_stream.append(mv[i+3])# k+=4# print(b_stream)def crc32(data): # 字节流crc = zlib.crc32(data)return crcdef crc32_b(data):crc = zlib.crc32(data).to_bytes(4, byteorder='big')return crc# png图片标识符png_signature = b"\x89PNG\r\n\x1a\n"# IHDR块ihdr = struct.pack("!IIBBBBB", width, height, 8, 2, 0, 0, 0) # 8 6 0 0 0# IHDR的CRC验证mid = crc32_b(b"IHDR" + ihdr)# 压缩图片数据bd = zlib.compress(bytes(b_stream))# IDAT的CRC验证crc_bytes = crc32_b(b"IDAT" + bd)idat_chunk = b"IDAT" + bd + crc_bytes# IEND块iend = b"\x00\x00\x00\x00IEND"# IEND的CRC验证crc_end = crc32_b(b"IEND")iend += crc_end# 写入图片操作,使用BytesIO来构建PNGpng_io = io.BytesIO()png_io.write(png_signature + b"\x00\x00\x00\rIHDR" + ihdr + mid)idat_header = struct.pack("!I", len(bd))png_io.write(idat_header + idat_chunk)png_io.write(iend)image_data = png_io.getvalue()# 剪切图片def Cut_png_image(x1, x2, y1, y2):global b_stream, image_dataprint(screenWidth, screenHeight)x = abs(x1 - x2)y = abs(y1 - y2)min_x = min(x1, x2)min_y = min(y1, y2)one_line_pixel = screenWidth * 3 + 1cut_stream = bytearray()for i in range(1, screenHeight + 1):if i >= min_y and i < min_y + y:cut_stream.append(0)cut_stream.extend(b_stream[one_line_pixel * (i - 1) + (min_x - 1) * 3 + 1:one_line_pixel * (i - 1) + (min_x + x) * 3 - 2])def crc32(data): # 字节流crc = zlib.crc32(data)return crcdef crc32_b(data):crc = zlib.crc32(data).to_bytes(4, byteorder='big')return crc# png图片标识符png_signature = b"\x89PNG\r\n\x1a\n"# IHDR块ihdr = struct.pack("!IIBBBBB", x, y, 8, 2, 0, 0, 0) # 8 6 0 0 0# IHDR的CRC验证mid = crc32_b(b"IHDR" + ihdr)# 压缩图片数据bd = zlib.compress(bytes(cut_stream))# IDAT的CRC验证crc_bytes = crc32_b(b"IDAT" + bd)idat_chunk = b"IDAT" + bd + crc_bytes# IEND块iend = b"\x00\x00\x00\x00IEND"# IEND的CRC验证crc_end = crc32_b(b"IEND")iend += crc_end# 写入图片操作,使用BytesIO来构建PNGpng_io = io.BytesIO()png_io.write(png_signature + b"\x00\x00\x00\rIHDR" + ihdr + mid)idat_header = struct.pack("!I", len(bd))png_io.write(idat_header + idat_chunk)png_io.write(iend)image_data = png_io.getvalue()# 剪切def Cut(x, y, width, height):global hdc_copy, hbitmap, old_bitmap,hdc_src,hdc_dest# 设置裁剪区域x_clip, y_clip, width_clip, height_clip = x, y, width, height # 裁剪区域的坐标和尺寸# 创建一个与屏幕兼容的内存设备上下文hdc_copy = gdi32.CreateCompatibleDC(hdc_src)# 创建对应大小位图hbitmap = gdi32.CreateCompatibleBitmap(hdc_src, width_clip, height_clip) # 创建大小为裁剪区域尺寸的兼容位图old_bitmap = gdi32.SelectObject(hdc_copy, hbitmap) # 将位图选入兼容设备上下文# 传递gdi32.BitBlt(hdc_copy, 0, 0, width_clip, height_clip, hdc_dest, x_clip, y_clip, SRCCOPY)# 复制def copy_bmp():global hbitmap# 这里是复制bmp图片内存对象# 加载必要的 Windows API 函数user32_1 = ctypes.windll.user32kernel32_1 = ctypes.windll.kernel32# 定义常量CF_BITMAP = 2# 打开剪贴板def OpenClipboard(hwnd):return user32_1.OpenClipboard(hwnd)# 关闭剪贴板def CloseClipboard():return user32_1.CloseClipboard()# 清空剪贴板def EmptyClipboard():return user32_1.EmptyClipboard()# 设置剪贴板数据def SetClipboardData(uFormat, hData):return user32_1.SetClipboardData(uFormat, hData)# 获取剪切板数据def GetClipboardData(uFormat):return user32_1.GetClipboardData(uFormat)# 全局分配内存def GlobalAlloc(uFlags, dwBytes):return kernel32_1.GlobalAlloc(uFlags, dwBytes)# 全局锁定内存def GlobalLock(hMem):return kernel32_1.GlobalLock(hMem)# 全局解锁内存def GlobalUnlock(hMem):return kernel32_1.GlobalUnlock(hMem)# 将图片复制到剪贴板def copy_bmp_to_clipboard():hwnd = 0if OpenClipboard(hwnd):try:EmptyClipboard()SetClipboardData(CF_BITMAP, hbitmap) # CF_BITMAP = 2finally:passCloseClipboard()# 复制copy_bmp_to_clipboard()"""绘画层"""class DrawingApp:def __init__(self):global popup, canvas, root, image_data# 初始化主窗口root = tk.Toplevel(top)# root.overrideredirect(True)bg_color = '#F0F0F0'root.config(bg=bg_color) # 背景色root.wm_attributes('-transparentcolor', bg_color)# 设置窗口为全屏模式root.attributes('-fullscreen', True)root.wm_attributes("-topmost", True) # 窗口置顶photo = PhotoImage(data=image_data)print(photo)# 创建Canvas用于传递canvas = tk.Canvas(root, width=screenWidth, height=screenHeight)self.root = rootself.root.wm_attributes("-topmost", True) # 窗口置顶self.root.attributes('-fullscreen', True) # 全屏self.canvas = canvasself.canvas.pack(expand=True)self.canvas.config(highlightthickness=0) # 设置canvas边框为0self.canvas.create_image(0, 0, image=photo, anchor=tk.NW)self.canvas.image = photoi1 = "iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAIAAAC0Ujn1AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAAEnQAABJ0Ad5mH3gAAABTSURBVEhL7cxBCgAhDENRb+7Rq0gWNqKUDrPRvFUR84v9Rmni0jUF4wWncYW9k+53AsbDKY0rTGmiNFGaXJme4TWMJi49U5r0fwkYD9v0d0o7Zg0Izd58BueWAwAAAABJRU5ErkJggg=="i2 = "iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAIAAAC0Ujn1AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAAEnQAABJ0Ad5mH3gAAACSSURBVEhL7ZbRDoAgCEWt9d/65+aClQgqczpndV7EhXc3YNPNe2/GsOM6gDWln1o75yBoQD4bpAFrLUY05vCvYn63gnDjfaSDLoD7izUn5MCVkfxdC9jO2lRoSBTWrPWMNgaqnSwnZF1rJqScI7uGMxrXAO4pk2oNiKZyTmMapTW8b66Bj9W6z41+E4v8DzOCMSddJdqD9ODtiwAAAABJRU5ErkJggg=="i3 = "iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAIAAAC0Ujn1AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAAEnQAABJ0Ad5mH3gAAAC3SURBVEhL3ZFBDsIwEAP5OU8vlna1pMHxupFAwJzaejI59Ha8jT9O31/IQaLSmWGhHOQdy7Q+VgiNp81usJJJ+lI3oEfmdEnmBcI/pae5rWtfpYGot3KTBtsfn2lqB9NkmlYa1GpqwE0DCI6TT1+RrtXUwEd+I6Bntj82aZoIWlmlRTfQ/ikNam67gfDnNDCjI/QISYNL9ZXM08CsC22ZBjgW5PtADvJ6lS4yM5CDxErv8Yvp43gAlXf3/IGNU4IAAAAASUVORK5CYII="i4 = "iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAIAAAC0Ujn1AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAABxSURBVEhL7ZZLDoAwCETRi8PNkSjxMyXRWlmY8DZlM29BmgyTqlIOs78JJKpxISLiUydB0NQ7zOxTP5aF+KEe8W6A4ctd207Oa/nnDyk1UGqg1ECpgVIj3jYrgx12U2BBMT8D2ssIrqd39jZVh9kFogUN7BwohR5/ywAAAABJRU5ErkJggg=="self.image1 = PhotoImage(data=base64.b64decode(i1))self.image2 = PhotoImage(data=base64.b64decode(i2))self.image3 = PhotoImage(data=base64.b64decode(i3))self.image4 = PhotoImage(data=base64.b64decode(i4))self.rect_id = Noneself.start_x = Noneself.start_y = Noneself.bind_events()def bind_events(self):self.canvas.bind("<ButtonPress-1>", self.on_button_press)self.canvas.bind("<B1-Motion>", self.on_mouse_drag)self.canvas.bind("<ButtonRelease-1>", self.on_button_release)self.canvas.bind("<Button-3>", self.on_right_click) # 鼠标右键def on_button_press(self, event):self.start_x = event.xself.start_y = event.yif popup:popup.destroy()## 右键点击销毁def on_right_click(self, event):destroy()global timestimes = 1def on_mouse_drag(self, event):if self.rect_id:self.canvas.delete(self.rect_id)self.rect_id = self.canvas.create_rectangle(self.start_x, self.start_y, event.x, event.y,outline='red',width=2)if popup:popup.destroy()def on_button_release(self, event):if self.rect_id:self.canvas.delete(self.rect_id)self.rect_id = self.canvas.create_rectangle(self.start_x, self.start_y, event.x, event.y,outline='red',width=2, fill='')"""交互层"""def copy_photo():x = min(self.start_x, event.x)y = min(self.start_y, event.y)width = abs(self.start_x - event.x)higth = abs(self.start_y - event.y)Cut(x, y, width, higth)copy_bmp()destroy()global timestimes = 1def save_photo():file_path = filedialog.asksaveasfilename(initialfile=datetime.now().strftime("%Y-%m-%d-%H-%M-%S"),defaultextension=".png",filetypes=[("PNG files", "*.png"), ("JPEG files", "*.jpg"),("All files", "*.*")])if file_path:Cut_png_image(self.start_x, event.x, self.start_y, event.y)with open(file_path, "wb") as f:f.write(image_data)destroy()global timestimes = 1def close_popup():destroy()global timestimes = 1def all_popup():file_path = filedialog.asksaveasfilename(initialfile=datetime.now().strftime("%Y-%m-%d-%H-%M-%S"),defaultextension=".png",filetypes=[("PNG files", "*.png"), ("JPEG files", "*.jpg"),("All files", "*.*")])if file_path:with open(file_path, "wb") as f:f.write(image_data)destroy()global timestimes = 1global popup# 弹出窗口bg_color = '#FFFFF1'popup = tk.Toplevel(self.root)popup.title("操作选项")popup.geometry("+" + str(event.x) + "+" + str(event.y))popup.wm_attributes("-topmost", True)popup.config(bg=bg_color) # 背景色popup.wm_attributes('-transparentcolor', bg_color) # 窗口色popup.overrideredirect(True) # 无边框tk.Button(popup, image=self.image1, text="复制", command=copy_photo).grid(row=0, column=0, padx=0,pady=0)tk.Button(popup, image=self.image2, text="保存", command=save_photo).grid(row=0, column=1, padx=0,pady=0)tk.Button(popup, image=self.image3, text="关闭", command=close_popup).grid(row=0, column=3, padx=0,pady=0)tk.Button(popup, image=self.image4, text="全部", command=all_popup).grid(row=0, column=2, padx=0,pady=0)"""启动层"""global timestimes = NoneFull_screen_capture(0, 0, screenWidth, screenHeight)png_image(screenWidth, screenHeight)if not len(str(hdc_src)) > 16:DrawingApp()# 百秒内截图处理time_end = 100for t in range(time_end):if times != None:CleanScreen()breakelse:time.sleep(1)if t == time_end-1:destroy()CleanScreen()print("释放内存")global rootroot = Nonepassstatus_thread = threading.Thread(target=screenshot)# 启动线程status_thread.start()# 创建按钮,并绑定事件处理函数button = tk.Button(top, text="截图", command=on_button_click, bg=bg_color, fg="#FFFFFF")button.place(x=window_width // 2 + 80, y=25)# 按键监控def key_state():global rootkey = 0x72 # F3prev_state = 0while True:time.sleep(0.02)# 获取按键状态state = user32.GetAsyncKeyState(key)if state & 0x8000:if not prev_state & 0x8000 and root == None:print("F3 键被按下")on_button_click()# elif prev_state & 0x8000:# print("F3 键被释放")prev_state = statekey_thread = threading.Thread(target=key_state)# 启动线程key_thread.start()top.mainloop()if __name__ == "__main__":main()
相关文章:
中等难度——python实现电子宠物和截图工具
import io # 文件处理 import nt # windows nt 库直接获取对应的磁盘空间 import time # 时间 import zlib # 加解密 import ctypes # 调用 import struct # 处理字节二进制 import base64 # 编解码 import threading # 线程 import tkinter as tk # tk from datetime…...
深入Android架构(从线程到AIDL)_22 IPC的Proxy-Stub设计模式04
目录 5、 谁来写Proxy及Stub类呢? 如何考虑人的分工 IA接口知识取得的难题 在编程上,有什么技术可以实现这个方法? 范例 5、 谁来写Proxy及Stub类呢? -- 强龙提供AIDL工具,给地头蛇产出Proxy和Stub类 如何考虑人的分工 由框架开发者…...
【MySQL数据库】基础总结
目录 前言 一、概述 二、 SQL 1. SQL通用语法 2. SQL分类 3. DDL 3.1 数据库操作 3.2 表操作 4. DML 5. DQL 5.1 基础查询 5.2 条件查询 5.3 聚合函数 5.4 分组查询 5.5 排序查询 5.6 分页查询 6. DCL 6.1 管理用户 6.2 权限控制 三、数据类型 1. 数值类…...
49_Lua调试
Lua提供了debug库用于创建自定义调试器,尽管Lua本身没有内置的调试器1。这个库允许开发者在程序运行时检查和控制执行流程,这对于开发过程中的错误查找和修复非常有用。 1.Debug库概述 debug库提供的函数可以分为两类:自省函数(introspection functions)和钩子函数(hoo…...
vue的KeepAlive应用(针对全部页面及单一页面进行缓存)
KeepAlive的作用是缓存包裹在其中的动态切换组件 当一个组件在 中被切换时,它的 activated 和 deactivated 生命周期钩子将被调用,用来替代 mounted 和 unmounted。这适用于 的直接子节点及其所有子孙节点。 缓存全部页面 将app.vue中的路由出口改为&am…...
lwip单网卡多ip的实现
1、今天要实现lwip的多个ip配置,本来以为需要自己修改很多核心代码 2、查阅资料才发现,lwip已经把接口留出来了 /** Define this to 1 and define LWIP_ARP_FILTER_NETIF_FN(pbuf, netif, type) * to a filter function that returns the correct neti…...
// Error: line 1: XGen: Candidate guides have not been associated!
Maya xgen 报错// Error: line 1: XGen: Candidate guides have not been associated! 复制下面粘贴到Maya脚本管理器python运行: import maya.cmds as cmds def connect_xgen_guides():guide_nodes cmds.ls(typexgmMakeGuide)for node in guide_nodes:downstream…...
第21篇 基于ARM A9处理器用汇编语言实现中断<三>
Q:怎样编写ARM A9处理器汇编语言代码配置按键端口产生中断? A:使用Intel Monitor Program创建中断程序时,Linker Section Presets下拉菜单中需选择Exceptions。主程序在.vectors代码段为ARM处理器设置异常向量表,在…...
mac homebrew配置使用
本文介绍mac上homebrew工具的安装、配置过程。homebrew功能类似于centos的yum,用于软件包的管理,使用上有命令的差异。 本次配置过程使用mac,看官方文档,在linux上也可以用,但我没试过,有兴趣的同学可以试试…...
慧集通(DataLinkX)iPaaS集成平台-业务建模之业务对象(三)
4.搜索配置 搜索配置是用于该业务对象发布后被其它业务对象的搜索组件调用时界面显示内容以及对应查询条件的配置;当我们选择一条业务对象然后点击功能按钮【搜索配置】,则进入业务对象的搜索配置维护界面。 在搜索配置的维护界面我们可以维护该业务对象…...
【redis初阶】环境搭建
目录 一、Ubuntu 安装 redis 二、Centos7 安装 redis 三、Centos8 安装 redis 四、redis客户端介绍 redis学习🥳 一、Ubuntu 安装 redis 使用 apt 安装 apt install redis -y 查看redis版本 redis-server --version 支持远程连接…...
salesforce sandbox的用户如何重置密码
在 Salesforce Sandbox 环境中,用户可以通过以下步骤重置密码: 方法 1:通过用户界面重置密码 登录到 Sandbox 环境: 打开 Sandbox 环境的 URL,通常形如 https://test.salesforce.com。输入用户名和密码。如果忘记密码&…...
做一个 简单的Django 《股票自选助手》显示 用akshare 库(A股数据获取)
图: 股票自选助手 这是一个基于 Django 开发的 A 股自选股票信息查看系统。系统使用 akshare 库获取实时股票数据,支持添加、删除和更新股票信息。 功能特点 支持添加自选股票实时显示股票价格和涨跌幅一键更新所有股票数据支持删除不需要的股票使用中…...
01、kafka知识点综合
kafka是一个优秀大吞吐消息队列,下面我就从实用的角度来讲讲kafka中,“kafka为何有大吞吐的机制”,“数据不丢失问题”,“精准一次消费问题” 01、kafka的架构组织和运行原理 kafka集群各个节点的名称叫broker,因为kaf…...
怎么用python写个唤醒睡眠电脑的脚本?
环境: win10 python3.12 问题描述: 怎么用python写个唤醒睡眠电脑的脚本? 解决方案: 1.唤醒处于睡眠状态的电脑通常不是通过编程直接实现的,而是依赖于硬件和操作系统提供的特性。对于Windows系统,可…...
【Linux】Linux开发:GDB调试器与Git版本控制工具指南
Linux相关知识点可以通过点击以下链接进行学习一起加油!初识指令指令进阶权限管理yum包管理与vim编辑器GCC/G编译器make与Makefile自动化构建 在 Linux 开发中,GDB 调试器和 Git 版本控制工具是开发者必备的利器。GDB 帮助快速定位代码问题,G…...
Git 的引用规格(refspec)语法
目录 引用规格语法格式常见用法强制 -f 和 的区别git fetch origin remote-branch:local-branch 和 git push origin local-branch:remote-branch 区别 引用规格语法格式 格式如下:[]<src>:<dst> 常见用法 # fetch git fetch origin <remote-bra…...
反转链表题目
文章目录 反转链表题目链接:[在线OJ](https://leetcode.cn/problems/reverse-linked-list/description/)题目详解思路1:思路1算法复杂度 思路2代码实现思路2算法复杂度 结语 欢迎大家来到我的博客,给生活来点impetus 让我们进入《题海探骊》…...
LED灯按键调光芯片、PWM调光IC、发光灯控制调光芯片
按键调光芯片,特别是LED灯使用PWM调光的芯片IC,是一种用于控制LED灯具亮度的集成电路,常用于台灯、壁灯、吊灯等照明设备中。这种芯片通过脉冲宽度调制(PWM)技术来调节LED的亮度,可以实现从最亮到最暗的平滑…...
Android Room 报错:too many SQL variables (code 1 SQLITE_ERROR) 原因及解决方法
报错信息: android.database.sqlite.SQLiteException: too many SQL variables (code 1 SQLITE_ERROR): while compiling: SELECT * FROM points WHERE id IN (?,?,?,...,?,?,?)SQLiteException: too many SQL variables 通常是由于一次查询或插入的 SQL 语句…...
linux 错误码总结
1,错误码的概念与作用 在Linux系统中,错误码是系统调用或库函数在执行失败时返回的特定数值,用于指示具体的错误类型。这些错误码通过全局变量errno来存储和传递,errno由操作系统维护,保存最近一次发生的错误信息。值得注意的是,errno的值在每次系统调用或函数调用失败时…...
ETLCloud可能遇到的问题有哪些?常见坑位解析
数据集成平台ETLCloud,主要用于支持数据的抽取(Extract)、转换(Transform)和加载(Load)过程。提供了一个简洁直观的界面,以便用户可以在不同的数据源之间轻松地进行数据迁移和转换。…...
汇编常见指令
汇编常见指令 一、数据传送指令 指令功能示例说明MOV数据传送MOV EAX, 10将立即数 10 送入 EAXMOV [EBX], EAX将 EAX 值存入 EBX 指向的内存LEA加载有效地址LEA EAX, [EBX4]将 EBX4 的地址存入 EAX(不访问内存)XCHG交换数据XCHG EAX, EBX交换 EAX 和 EB…...
SiFli 52把Imagie图片,Font字体资源放在指定位置,编译成指定img.bin和font.bin的问题
分区配置 (ptab.json) img 属性介绍: img 属性指定分区存放的 image 名称,指定的 image 名称必须是当前工程生成的 binary 。 如果 binary 有多个文件,则以 proj_name:binary_name 格式指定文件名, proj_name 为工程 名&…...
数据结构:递归的种类(Types of Recursion)
目录 尾递归(Tail Recursion) 什么是 Loop(循环)? 复杂度分析 头递归(Head Recursion) 树形递归(Tree Recursion) 线性递归(Linear Recursion)…...
Python实现简单音频数据压缩与解压算法
Python实现简单音频数据压缩与解压算法 引言 在音频数据处理中,压缩算法是降低存储成本和传输效率的关键技术。Python作为一门灵活且功能强大的编程语言,提供了丰富的库和工具来实现音频数据的压缩与解压。本文将通过一个简单的音频数据压缩与解压算法…...
DiscuzX3.5发帖json api
参考文章:PHP实现独立Discuz站外发帖(直连操作数据库)_discuz 发帖api-CSDN博客 简单改造了一下,适配我自己的需求 有一个站点存在多个采集站,我想通过主站拿标题,采集站拿内容 使用到的sql如下 CREATE TABLE pre_forum_post_…...
leetcode73-矩阵置零
leetcode 73 思路 记录 0 元素的位置:遍历整个矩阵,找出所有值为 0 的元素,并将它们的坐标记录在数组zeroPosition中置零操作:遍历记录的所有 0 元素位置,将每个位置对应的行和列的所有元素置为 0 具体步骤 初始化…...
起重机起升机构的安全装置有哪些?
起重机起升机构的安全装置是保障吊装作业安全的关键部件,主要用于防止超载、失控、断绳等危险情况。以下是常见的安全装置及其功能和原理: 一、超载保护装置(核心安全装置) 1. 起重量限制器 功能:实时监测起升载荷&a…...
【java】【服务器】线程上下文丢失 是指什么
目录 ■前言 ■正文开始 线程上下文的核心组成部分 为什么会出现上下文丢失? 直观示例说明 为什么上下文如此重要? 解决上下文丢失的关键 总结 ■如果我想在servlet中使用线程,代码应该如何实现 推荐方案:使用 ManagedE…...
