当前位置: 首页 > news >正文

为什么有些网站更新的信息看不到绍兴seo推广

为什么有些网站更新的信息看不到,绍兴seo推广,湘潭网站建设公司有哪些,前端静态网页模板目录 Python#xff5c;GIF 解析与构建#xff08;6#xff09;#xff1a;手搓 tk 录制工具 一、工具功能概览 二、核心架构设计 1. 帧率控制模块 2. 屏幕捕获模块 3. 主应用模块 三、关键技术解析 1. 屏幕捕获技术 2. 帧率控制原理 3. 透明窗口实现 四、使用指…目录 PythonGIF 解析与构建6手搓 tk 录制工具 一、工具功能概览 二、核心架构设计 1. 帧率控制模块 2. 屏幕捕获模块 3. 主应用模块 三、关键技术解析 1. 屏幕捕获技术 2. 帧率控制原理 3. 透明窗口实现 四、使用指南 1. 基本操作 2. 高级技巧 五、优化方向 六、总结 PythonGIF 解析与构建6手搓 tk 录制工具 在 GIF 动图的制作流程中屏幕录制是一个非常实用的功能。通过 Python 的 Tkinter 库我们可以轻松构建一个轻量级的 GIF 录制工具实现自定义区域录制、帧率控制等功能。 一、工具功能概览 我们构建的 GIF 录制工具具备以下核心功能 自定义录制区域可自由设置录制区域的位置和大小帧率控制支持自定义帧率设置满足不同场景需求实时坐标显示显示录制区域在屏幕上的精确坐标轻量级界面基于 Tkinter 构建的简洁操作界面窗口拖动支持拖动窗口调整位置 这个工具适合用于制作教程演示、软件操作录制等场景相比专业录制软件更加轻量灵活。 二、核心架构设计 工具采用模块化设计主要包含三个核心类 1. 帧率控制模块 control_frame类负责管理录制帧率确保录制过程保持稳定的帧速率 计算每帧的理想间隔时间监测实际处理时间并进行补偿统计实际帧率和总录制时间 该模块通过time.sleep()实现精确的时间控制确保录制的 GIF 流畅无卡顿。 2. 屏幕捕获模块 ScreenshotData类封装了屏幕截图功能基于 Windows API 实现 使用ctypes调用 GDI32 和 USER32 动态链接库支持获取屏幕 DPI 并计算缩放比例通过BitBlt函数实现高效屏幕拷贝提取像素数据用于后续 GIF 生成 这个模块解决了 Python 中高效屏幕捕获的问题为 GIF 录制提供了基础数据。 3. 主应用模块 GIFALL类是主应用类负责构建 GUI 界面和协调各模块工作 构建可视化操作界面包括参数设置和控制按钮处理用户交互如窗口拖动、参数修改协调屏幕捕获和帧率控制模块完成录制流程实时更新显示录制区域坐标 三、关键技术解析 1. 屏幕捕获技术 在 Windows 环境下实现屏幕捕获我们采用了 GDI 绘图接口 # 通过BitBlt函数拷贝屏幕内容 SRCCOPY 0x00CC0020 self.gdi32.BitBlt(hdc_dest, 0, 0, width, height, hdc_src, x, y, SRCCOPY)这种方法相比 Python 的 PIL 库截图更加高效能够满足高帧率录制的需求。通过定义 Windows API 中的结构体我们可以直接获取原始像素数据 # 定义RGB颜色结构体 class RGBQUAD(ctypes.Structure):_fields_ [(rgbBlue, ctypes.c_ubyte),(rgbGreen, ctypes.c_ubyte),(rgbRed, ctypes.c_ubyte),(rgbReserved, ctypes.c_ubyte)]2. 帧率控制原理 帧率控制的核心在于计算每帧的理想时间并进行实时补偿 def wait(self):spend self.spend()true_frame self.fps_count / (time.time() - self.time_all)if true_frame self.fps:if self.time_one_frame - spend 0:time.sleep(self.time_one_frame - spend)这段代码会计算实际处理一帧所用的时间并与理想时间比较通过time.sleep()进行补偿确保整体帧率稳定。 3. 透明窗口实现 为了让录制工具不遮挡屏幕内容我们实现了透明窗口效果 # 设置透明背景色 self.bg_color #FFFFF1 self.root.config(bgself.bg_color) self.root.wm_attributes(-transparentcolor, self.bg_color)通过设置窗口的透明颜色属性使特定颜色的区域变得透明提升使用体验。 四、使用指南 1. 基本操作 启动程序后会看到一个透明的录制窗口通过输入框设置录制区域的宽度、高度和坐标设置合适的帧率建议 10-30fps和总帧数点击 开始录制 按钮开始录制录制完成后会显示总耗时和平均帧率 2. 高级技巧 拖动窗口可以调整录制区域的位置实时坐标显示帮助精确定位录制区域根据录制内容特性调整帧率 静态内容10-15fps 即可动态内容24-30fps 更流畅 总帧数控制录制时长时长 总帧数 / 帧率 五、优化方向 当前版本的录制工具还有很多可以改进的地方 GIF 生成功能当前只完成了屏幕捕获需要添加像素数据到 GIF 的转换功能文件保存增加录制结果保存功能支持自定义文件名和保存路径区域选择优化添加鼠标拖动选择区域的功能提升操作便捷性跨平台支持当前仅支持 Windows 平台。 六、总结 通过这个基于 Tkinter 的 GIF 录制工具我们深入了解了 Python 在图形界面和系统接口调用方面的能力。从屏幕捕获到帧率控制再到用户界面设计每个环节都蕴含着丰富的技术细节。 代码如下 import time import ctypes import tkinter as tk# 控制帧率 class control_frame():def __init__(self):self.start_time float() # 每次启动时间self.fps int(10) # fpsself.time_one_frame 1 / self.fps # 补正时间self.fps_count 0 # 总帧率self.time_all time.time() # 启动时间# 启动def start(self):self.start_time time.time()self.fps_count 1# 花销def spend(self):spend time.time() - self.start_timereturn spend# 等待def wait(self):spend self.spend()true_frame self.fps_count / (time.time() - self.time_all)if true_frame self.fps:if self.time_one_frame - spend 0:time.sleep(self.time_one_frame - spend)# 获取屏幕数据 class ScreenshotData():def __init__(self):self.gdi32 ctypes.windll.gdi32self.user32 ctypes.windll.user32# 定义常量SM_CXSCREEN 0SM_CYSCREEN 1# 缩放比例zoom 1hdc self.user32.GetDC(None)try:dpi self.gdi32.GetDeviceCaps(hdc, 88)zoom dpi / 96.0finally:self.user32.ReleaseDC(None, hdc)self.screenWidth int(self.user32.GetSystemMetrics(SM_CXSCREEN) * zoom)self.screenHeight int(self.user32.GetSystemMetrics(SM_CYSCREEN) * zoom)# 屏幕截取def capture_screen(self, x, y, width, height):# 获取桌面窗口句柄hwnd self.user32.GetDesktopWindow()# 获取桌面窗口的设备上下文hdc_src self.user32.GetDC(hwnd)if len(str(hdc_src)) 16:return 0# 创建一个与屏幕兼容的内存设备上下文hdc_dest self.gdi32.CreateCompatibleDC(hdc_src)# 创建一个位图bmp self.gdi32.CreateCompatibleBitmap(hdc_src, width, height)# 将位图选入内存设备上下文old_bmp self.gdi32.SelectObject(hdc_dest, bmp)# 定义SRCCOPY常量SRCCOPY 0x00CC0020# 捕获屏幕self.gdi32.BitBlt(hdc_dest, 0, 0, width, height, hdc_src, x, y, SRCCOPY)gdi32.BitBlt(hdc_src, # 目标设备上下文 x_dest, # 目标矩形左上角的x坐标 y_dest, # 目标矩形左上角的y坐标 width, # 宽度 height, # 高度 hdc_dest, # 源设备上下文 x_src, # 源矩形左上角的x坐标通常是0 y_src, # 源矩形左上角的y坐标通常是0 SRCCOPY) # 复制选项# 定义 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# 填充 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 self.gdi32.GetDIBits(hdc_src, bmp, 0, height, pixel_data, ctypes.byref(bmi), DIB_RGB_COLORS)if ret 0:print(GetDIBits failed:, ctypes.WinError())# 恢复设备上下文self.gdi32.SelectObject(hdc_dest, old_bmp)# 删除内存设备上下文self.gdi32.DeleteDC(hdc_dest)# 释放桌面窗口的设备上下文self.user32.ReleaseDC(hwnd, hdc_src)# bmp已经被处理现在删除它self.gdi32.DeleteObject(bmp)return pixel_data# GIF录制系统 class GIFALL():def __init__(self, root):self.root rootself.root.title(gif录制)self.root.geometry(500x250)self.root.attributes(-topmost, True) # 设置窗口置顶# self.root.overrideredirect(True)# 隐藏标题栏self.width 100self.height 100self.x_axis 0self.y_axis 0self.fps_choose 10self.frame_total 100self.frame_count 0self.recording False # 初始化录制状态# 左上右下坐标self.topleft_x 0self.topleft_y 0self.bottomright_x 0self.bottomright_y 0# 设置透明背景色self.bg_color #FFFFF1self.root.config(bgself.bg_color)self.root.wm_attributes(-transparentcolor, self.bg_color)# 创建主框架self.main_frame tk.Frame(root, bg#FFFFF1, bd0)self.main_frame.pack(filltk.BOTH, expandTrue, padx0, pady0)# 左侧透明取景区域self.left_frame tk.Frame(self.main_frame, bg#FFFFF1)self.left_frame.pack(sidetk.LEFT, filltk.BOTH)# 右侧控制面板self.right_frame tk.Frame(self.main_frame, bg#FFFFF1, width250)self.right_frame.pack(sidetk.RIGHT, filltk.Y)self.right_frame.pack_propagate(False)# 在左侧区域添加取景框self.create_viewfinder()# 添加右侧控制面板内容self.create_control_panel()# 添加窗口拖动功能self.root.bind(ButtonPress-1, self.start_move)self.root.bind(ButtonRelease-1, self.stop_move)self.root.bind(B1-Motion, self.on_move)# 启动坐标更新循环self.update_coordinates()# 录制栏def create_viewfinder(self):# 创建取景框canvas_width self.width self.x_axis 2canvas_height self.height self.y_axis 2self.canvas tk.Canvas(self.left_frame,bg#FFFFF1,widthcanvas_width,heightcanvas_height,highlightthickness0)self.canvas.pack(padx0, pady0)# 绘制取景框self.viewfinder self.canvas.create_rectangle(self.x_axis, self.y_axis, self.x_axis self.width 2, self.y_axis self.height 2,outline#00BFFF,width2,dash(5, 20))# 操作栏def create_control_panel(self):# 尺寸信息size_frame tk.Frame(self.right_frame, bgself.bg_color)size_frame.pack(pady0, padx5, filltk.X)self.width_vr tk.StringVar(valuestr(self.width))self.height_vr tk.StringVar(valuestr(self.height))self.x_axis_vr tk.StringVar(valuestr(self.x_axis))self.y_axis_vr tk.StringVar(valuestr(self.y_axis))self.fps_vr tk.StringVar(valuestr(self.fps_choose))self.frame_vr tk.StringVar(valuestr(self.frame_total))# 绑定变量变化事件self.width_vr.trace_add(write, self.on_dimension_change)self.height_vr.trace_add(write, self.on_dimension_change)self.x_axis_vr.trace_add(write, self.on_dimension_change)self.y_axis_vr.trace_add(write, self.on_dimension_change)self.fps_vr.trace_add(write, self.on_fps_change) # 绑定帧率变化事件self.frame_vr.trace_add(write, self.on_fps_change) # 绑定帧率变化事件# 创建宽度输入框tk.Label(size_frame, text宽度:).grid(row0, column0, padx5, pady5, stickyw)tk.Entry(size_frame, textvariableself.width_vr, width5).grid(row0, column1, padx5, pady5)# 创建高度输入框tk.Label(size_frame, text高度:).grid(row0, column3, padx5, pady5, stickyw)tk.Entry(size_frame, textvariableself.height_vr, width5).grid(row0, column4, padx5, pady5)# 创建s轴输入框tk.Label(size_frame, textx轴:).grid(row1, column0, padx5, pady5, stickyw)tk.Entry(size_frame, textvariableself.x_axis_vr, width5).grid(row1, column1, padx5, pady5)# 创建y轴输入框tk.Label(size_frame, texty轴:).grid(row1, column3, padx5, pady5, stickyw)tk.Entry(size_frame, textvariableself.y_axis_vr, width5).grid(row1, column4, padx5, pady5)# 创建帧率输入框tk.Label(size_frame, text帧率:).grid(row2, column0, padx5, pady5, stickyw)tk.Entry(size_frame, textvariableself.fps_vr, width5).grid(row2, column1, padx5, pady5)# 创建总帧率输入框tk.Label(size_frame, text总帧率:).grid(row2, column3, padx5, pady5, stickyw)tk.Entry(size_frame, textvariableself.frame_vr, width5).grid(row2, column4, padx5, pady5)# 添加坐标显示标签self.coord_frame tk.Frame(self.right_frame, bgself.bg_color)self.coord_frame.pack(pady5)self.topleft_label tk.Label(self.coord_frame,text(0, 0),bgself.bg_color,fg#FFFFFF,font(Arial, 10))self.topleft_label.grid(row0, column0)self.bottomright_label tk.Label(self.coord_frame,text(0, 0),bgself.bg_color,fg#FFFFFF,font(Arial, 10))self.bottomright_label.grid(row0, column1)# 控制按钮button_frame tk.Frame(self.right_frame, bgself.bg_color)button_frame.pack(pady10, padx5, filltk.X)self.record_btn tk.Button(button_frame,text开始录制,commandself.toggle_recording,bg#E74C3C,fgwhite,font(Arial, 12, bold),reliefflat,padx20,pady10,width15)self.record_btn.pack(pady10)tk.Button(button_frame,text退出应用,commandself.root.destroy,bg#000011,fgwhite,font(Arial, 12),reliefflat,padx0,pady0).pack(pady5)# 更新尺寸def on_dimension_change(self, *args):当尺寸输入框内容变化时更新取景框尺寸try:# 获取新的尺寸值new_width int(self.width_vr.get())new_height int(self.height_vr.get())new_x_axis int(self.x_axis_vr.get())new_y_axis int(self.y_axis_vr.get())# 验证尺寸有效性if new_width 0 and new_height 0:# 锁定if new_width 500:new_width 500if new_height 500:new_height 500# 更新类属性self.width new_widthself.height new_height# 锁定if new_x_axis 500:new_x_axis 500if new_y_axis 500:new_y_axis 500if new_x_axis :new_x_axis 0# 更新类属性self.x_axis new_x_axisself.y_axis new_y_axis# 更新取景框self.update_viewfinder()# 更新坐标显示self.update_coordinates()except ValueError:# 输入非数字时忽略pass# 更新重新绘制def update_viewfinder(self):更新取景框尺寸# 重新配置Canvas大小self.canvas.config(widthself.width self.x_axis 2, heightself.height self.y_axis 2)# 更新取景框矩形self.canvas.coords(self.viewfinder, self.x_axis, self.y_axis, self.width self.x_axis 2,self.height self.y_axis 2)# 强制刷新Canvasself.canvas.update_idletasks()# 更新坐标def update_coordinates(self):更新取景框的坐标显示titlebar_height 30border_width 1correction_value titlebar_height border_widthcorrection_left_value 8# 获取窗口在屏幕上的位置window_x self.root.winfo_x() correction_left_valuewindow_y self.root.winfo_y() correction_value# 计算取景框在屏幕上的绝对坐标self.topleft_x window_x self.x_axis 1self.topleft_y window_y self.y_axis 1self.bottomright_x self.topleft_x self.width - 1self.bottomright_y self.topleft_y self.height - 1# 更新坐标标签self.topleft_label.config(textf({self.topleft_x},{self.topleft_y}))self.bottomright_label.config(textf({self.bottomright_x},{self.bottomright_y}))# 每秒更新一次坐标self.root.after(1000, self.update_coordinates)# 更新显示def on_fps_change(self, *args):当帧率输入框内容变化时更新显示try:new_fps int(self.fps_vr.get())new_frame int(self.frame_vr.get())# 锁定if new_fps 1:new_fps 1elif new_fps 100:new_fps 100self.fps_choose new_fpsif new_frame 1:new_frame 1self.frame_total new_frameexcept ValueError:# 输入非数字时忽略pass# 录制def toggle_recording(self):if not self.recording:# 开始录制self.recording Trueself.record_btn.config(text停止录制, bg#2ECC71)Screenshot ScreenshotData()wait control_frame()# 帧率设置wait.fps self.fps_chooseself.st time.time()def work():wait.start()data Screenshot.capture_screen(self.topleft_x, self.topleft_y, self.bottomright_x-self.topleft_x1, self.bottomright_y-self.topleft_y1)wait.wait()# print(self.topleft_x, self.topleft_y, self.bottomright_x-self.topleft_x1, self.bottomright_y-self.topleft_y1)self.frame_count1if self.frame_count self.frame_total:self.frame_count 0self.recording Falseself.record_btn.config(text开始录制, bg#E74C3C)print(耗费时间,time.time()-self.st)print(秒平均帧,self.frame_total/(time.time()-self.st))return Trueself.root.after(1, work)self.root.after(1,work)else:# 停止录制self.recording Falseself.record_btn.config(text开始录制, bg#E74C3C)# 窗口拖动功能def start_move(self, event):self.x event.xself.y event.ydef stop_move(self, event):self.x Noneself.y Nonedef on_move(self, event):deltax event.x - self.xdeltay event.y - self.yx self.root.winfo_x() deltaxy self.root.winfo_y() deltayself.root.geometry(f{x}{y})# 窗口移动后更新坐标self.update_coordinates()if __name__ __main__:root tk.Tk()app GIFALL(root)root.mainloop()import time import ctypes import tkinter as tk# 控制帧率 class control_frame():def __init__(self):self.start_time float() # 每次启动时间self.fps int(10) # fpsself.time_one_frame 1 / self.fps # 补正时间self.fps_count 0 # 总帧率self.time_all time.time() # 启动时间# 启动def start(self):self.start_time time.time()self.fps_count 1# 花销def spend(self):spend time.time() - self.start_timereturn spend# 等待def wait(self):spend self.spend()true_frame self.fps_count / (time.time() - self.time_all)if true_frame self.fps:if self.time_one_frame - spend 0:time.sleep(self.time_one_frame - spend)# 获取屏幕数据 class ScreenshotData():def __init__(self):self.gdi32 ctypes.windll.gdi32self.user32 ctypes.windll.user32# 定义常量SM_CXSCREEN 0SM_CYSCREEN 1# 缩放比例zoom 1hdc self.user32.GetDC(None)try:dpi self.gdi32.GetDeviceCaps(hdc, 88)zoom dpi / 96.0finally:self.user32.ReleaseDC(None, hdc)self.screenWidth int(self.user32.GetSystemMetrics(SM_CXSCREEN) * zoom)self.screenHeight int(self.user32.GetSystemMetrics(SM_CYSCREEN) * zoom)# 屏幕截取def capture_screen(self, x, y, width, height):# 获取桌面窗口句柄hwnd self.user32.GetDesktopWindow()# 获取桌面窗口的设备上下文hdc_src self.user32.GetDC(hwnd)if len(str(hdc_src)) 16:return 0# 创建一个与屏幕兼容的内存设备上下文hdc_dest self.gdi32.CreateCompatibleDC(hdc_src)# 创建一个位图bmp self.gdi32.CreateCompatibleBitmap(hdc_src, width, height)# 将位图选入内存设备上下文old_bmp self.gdi32.SelectObject(hdc_dest, bmp)# 定义SRCCOPY常量SRCCOPY 0x00CC0020# 捕获屏幕self.gdi32.BitBlt(hdc_dest, 0, 0, width, height, hdc_src, x, y, SRCCOPY)gdi32.BitBlt(hdc_src, # 目标设备上下文 x_dest, # 目标矩形左上角的x坐标 y_dest, # 目标矩形左上角的y坐标 width, # 宽度 height, # 高度 hdc_dest, # 源设备上下文 x_src, # 源矩形左上角的x坐标通常是0 y_src, # 源矩形左上角的y坐标通常是0 SRCCOPY) # 复制选项# 定义 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# 填充 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 self.gdi32.GetDIBits(hdc_src, bmp, 0, height, pixel_data, ctypes.byref(bmi), DIB_RGB_COLORS)if ret 0:print(GetDIBits failed:, ctypes.WinError())# 恢复设备上下文self.gdi32.SelectObject(hdc_dest, old_bmp)# 删除内存设备上下文self.gdi32.DeleteDC(hdc_dest)# 释放桌面窗口的设备上下文self.user32.ReleaseDC(hwnd, hdc_src)# bmp已经被处理现在删除它self.gdi32.DeleteObject(bmp)return pixel_data# GIF录制系统 class GIFALL():def __init__(self, root):self.root rootself.root.title(gif录制)self.root.geometry(500x250)self.root.attributes(-topmost, True) # 设置窗口置顶# self.root.overrideredirect(True)# 隐藏标题栏self.width 100self.height 100self.x_axis 0self.y_axis 0self.fps_choose 10self.frame_total 100self.frame_count 0self.recording False # 初始化录制状态# 左上右下坐标self.topleft_x 0self.topleft_y 0self.bottomright_x 0self.bottomright_y 0# 设置透明背景色self.bg_color #FFFFF1self.root.config(bgself.bg_color)self.root.wm_attributes(-transparentcolor, self.bg_color)# 创建主框架self.main_frame tk.Frame(root, bg#FFFFF1, bd0)self.main_frame.pack(filltk.BOTH, expandTrue, padx0, pady0)# 左侧透明取景区域self.left_frame tk.Frame(self.main_frame, bg#FFFFF1)self.left_frame.pack(sidetk.LEFT, filltk.BOTH)# 右侧控制面板self.right_frame tk.Frame(self.main_frame, bg#FFFFF1, width250)self.right_frame.pack(sidetk.RIGHT, filltk.Y)self.right_frame.pack_propagate(False)# 在左侧区域添加取景框self.create_viewfinder()# 添加右侧控制面板内容self.create_control_panel()# 添加窗口拖动功能self.root.bind(ButtonPress-1, self.start_move)self.root.bind(ButtonRelease-1, self.stop_move)self.root.bind(B1-Motion, self.on_move)# 启动坐标更新循环self.update_coordinates()# 录制栏def create_viewfinder(self):# 创建取景框canvas_width self.width self.x_axis 2canvas_height self.height self.y_axis 2self.canvas tk.Canvas(self.left_frame,bg#FFFFF1,widthcanvas_width,heightcanvas_height,highlightthickness0)self.canvas.pack(padx0, pady0)# 绘制取景框self.viewfinder self.canvas.create_rectangle(self.x_axis, self.y_axis, self.x_axis self.width 2, self.y_axis self.height 2,outline#00BFFF,width2,dash(5, 20))# 操作栏def create_control_panel(self):# 尺寸信息size_frame tk.Frame(self.right_frame, bgself.bg_color)size_frame.pack(pady0, padx5, filltk.X)self.width_vr tk.StringVar(valuestr(self.width))self.height_vr tk.StringVar(valuestr(self.height))self.x_axis_vr tk.StringVar(valuestr(self.x_axis))self.y_axis_vr tk.StringVar(valuestr(self.y_axis))self.fps_vr tk.StringVar(valuestr(self.fps_choose))self.frame_vr tk.StringVar(valuestr(self.frame_total))# 绑定变量变化事件self.width_vr.trace_add(write, self.on_dimension_change)self.height_vr.trace_add(write, self.on_dimension_change)self.x_axis_vr.trace_add(write, self.on_dimension_change)self.y_axis_vr.trace_add(write, self.on_dimension_change)self.fps_vr.trace_add(write, self.on_fps_change) # 绑定帧率变化事件self.frame_vr.trace_add(write, self.on_fps_change) # 绑定帧率变化事件# 创建宽度输入框tk.Label(size_frame, text宽度:).grid(row0, column0, padx5, pady5, stickyw)tk.Entry(size_frame, textvariableself.width_vr, width5).grid(row0, column1, padx5, pady5)# 创建高度输入框tk.Label(size_frame, text高度:).grid(row0, column3, padx5, pady5, stickyw)tk.Entry(size_frame, textvariableself.height_vr, width5).grid(row0, column4, padx5, pady5)# 创建s轴输入框tk.Label(size_frame, textx轴:).grid(row1, column0, padx5, pady5, stickyw)tk.Entry(size_frame, textvariableself.x_axis_vr, width5).grid(row1, column1, padx5, pady5)# 创建y轴输入框tk.Label(size_frame, texty轴:).grid(row1, column3, padx5, pady5, stickyw)tk.Entry(size_frame, textvariableself.y_axis_vr, width5).grid(row1, column4, padx5, pady5)# 创建帧率输入框tk.Label(size_frame, text帧率:).grid(row2, column0, padx5, pady5, stickyw)tk.Entry(size_frame, textvariableself.fps_vr, width5).grid(row2, column1, padx5, pady5)# 创建总帧率输入框tk.Label(size_frame, text总帧率:).grid(row2, column3, padx5, pady5, stickyw)tk.Entry(size_frame, textvariableself.frame_vr, width5).grid(row2, column4, padx5, pady5)# 添加坐标显示标签self.coord_frame tk.Frame(self.right_frame, bgself.bg_color)self.coord_frame.pack(pady5)self.topleft_label tk.Label(self.coord_frame,text(0, 0),bgself.bg_color,fg#FFFFFF,font(Arial, 10))self.topleft_label.grid(row0, column0)self.bottomright_label tk.Label(self.coord_frame,text(0, 0),bgself.bg_color,fg#FFFFFF,font(Arial, 10))self.bottomright_label.grid(row0, column1)# 控制按钮button_frame tk.Frame(self.right_frame, bgself.bg_color)button_frame.pack(pady10, padx5, filltk.X)self.record_btn tk.Button(button_frame,text开始录制,commandself.toggle_recording,bg#E74C3C,fgwhite,font(Arial, 12, bold),reliefflat,padx20,pady10,width15)self.record_btn.pack(pady10)tk.Button(button_frame,text退出应用,commandself.root.destroy,bg#000011,fgwhite,font(Arial, 12),reliefflat,padx0,pady0).pack(pady5)# 更新尺寸def on_dimension_change(self, *args):当尺寸输入框内容变化时更新取景框尺寸try:# 获取新的尺寸值new_width int(self.width_vr.get())new_height int(self.height_vr.get())new_x_axis int(self.x_axis_vr.get())new_y_axis int(self.y_axis_vr.get())# 验证尺寸有效性if new_width 0 and new_height 0:# 锁定if new_width 500:new_width 500if new_height 500:new_height 500# 更新类属性self.width new_widthself.height new_height# 锁定if new_x_axis 500:new_x_axis 500if new_y_axis 500:new_y_axis 500if new_x_axis :new_x_axis 0# 更新类属性self.x_axis new_x_axisself.y_axis new_y_axis# 更新取景框self.update_viewfinder()# 更新坐标显示self.update_coordinates()except ValueError:# 输入非数字时忽略pass# 更新重新绘制def update_viewfinder(self):更新取景框尺寸# 重新配置Canvas大小self.canvas.config(widthself.width self.x_axis 2, heightself.height self.y_axis 2)# 更新取景框矩形self.canvas.coords(self.viewfinder, self.x_axis, self.y_axis, self.width self.x_axis 2,self.height self.y_axis 2)# 强制刷新Canvasself.canvas.update_idletasks()# 更新坐标def update_coordinates(self):更新取景框的坐标显示titlebar_height 30border_width 1correction_value titlebar_height border_widthcorrection_left_value 8# 获取窗口在屏幕上的位置window_x self.root.winfo_x() correction_left_valuewindow_y self.root.winfo_y() correction_value# 计算取景框在屏幕上的绝对坐标self.topleft_x window_x self.x_axis 1self.topleft_y window_y self.y_axis 1self.bottomright_x self.topleft_x self.width - 1self.bottomright_y self.topleft_y self.height - 1# 更新坐标标签self.topleft_label.config(textf({self.topleft_x},{self.topleft_y}))self.bottomright_label.config(textf({self.bottomright_x},{self.bottomright_y}))# 每秒更新一次坐标self.root.after(1000, self.update_coordinates)# 更新显示def on_fps_change(self, *args):当帧率输入框内容变化时更新显示try:new_fps int(self.fps_vr.get())new_frame int(self.frame_vr.get())# 锁定if new_fps 1:new_fps 1elif new_fps 100:new_fps 100self.fps_choose new_fpsif new_frame 1:new_frame 1self.frame_total new_frameexcept ValueError:# 输入非数字时忽略pass# 录制def toggle_recording(self):if not self.recording:# 开始录制self.recording Trueself.record_btn.config(text停止录制, bg#2ECC71)Screenshot ScreenshotData()wait control_frame()# 帧率设置wait.fps self.fps_chooseself.st time.time()def work():wait.start()data Screenshot.capture_screen(self.topleft_x, self.topleft_y, self.bottomright_x-self.topleft_x1, self.bottomright_y-self.topleft_y1)wait.wait()# print(self.topleft_x, self.topleft_y, self.bottomright_x-self.topleft_x1, self.bottomright_y-self.topleft_y1)self.frame_count1if self.frame_count self.frame_total:self.frame_count 0self.recording Falseself.record_btn.config(text开始录制, bg#E74C3C)print(耗费时间,time.time()-self.st)print(秒平均帧,self.frame_total/(time.time()-self.st))return Trueself.root.after(1, work)self.root.after(1,work)else:# 停止录制self.recording Falseself.record_btn.config(text开始录制, bg#E74C3C)# 窗口拖动功能def start_move(self, event):self.x event.xself.y event.ydef stop_move(self, event):self.x Noneself.y Nonedef on_move(self, event):deltax event.x - self.xdeltay event.y - self.yx self.root.winfo_x() deltaxy self.root.winfo_y() deltayself.root.geometry(f{x}{y})# 窗口移动后更新坐标self.update_coordinates()if __name__ __main__:root tk.Tk()app GIFALL(root)root.mainloop()
http://www.w-s-a.com/news/542526/

相关文章:

  • 兼职做网站赚钱吗图片设计制作哪个软件好手机
  • 做手机旅游网站智慧校园登录入口
  • 莆田网站建设维护国外极简网站
  • 百度怎样收录网站缪斯设计集团
  • 网站建设在开封找谁做wordpress 数据转换
  • 旅游网站开发的流程江苏付费网络推广培训
  • 网站软文标题2018wordpress主题
  • 德清网站设计wordpress免登录发布接
  • 可以做游戏的网站有哪些客户关系管理系统的主要功能
  • 整人关不掉的网站怎么做广东省网站免备案表
  • 网站设计素材edu域名网站
  • 中山学校的网站建设wordpress文章图片显示不出
  • 兰溪城市建设规划网站网站联盟的基本流程
  • 免费推广网站注册入口小说阅读网站怎么建设
  • 新网站怎么做网络推广怎么做企业网站排名
  • jsp商业网站开发网站链接如何做二维码
  • 江苏高校品牌专业建设网站怎么制作网站搜索窗口
  • 北京app建设 网站开发公司织梦网站seo
  • 大学网站 作风建设专题汽车配件外贸出口公司
  • 东莞做网站系统购物网站建设精英
  • 建设vip网站相关视频网站营销建设公司
  • 微站直播平台杭州seo按天计费
  • seo 新旧网站 两个域名福州设计网站建设
  • 如何做网站客户端如何做网络营销网站
  • 苏州网站建设制度打鱼网站建设
  • 瓜子二手车直卖网上海小红书seo
  • 天津中小企业网站制作珠海做网站的
  • 网站排名影响因素最牛的科技网站建设
  • 长春网站建设公司怎么样电商网站建设与开发期末考试
  • 品牌网站建设搭建国内外网站建设