大家好,欢迎回到“Python五分钟”,我是赛博红兔。前两天,我在教家里人怎么用一款软件。就很简单几个步骤,但是因为家人年纪大了老是记不住。我突然想到这么一个问题:要是我能录制屏幕上某个特定窗口,然后把它保存为一个小小的GIF动图。那么他们就可以随时打开跟着操作,比文字更加直观,也不用录制一个大视频。结果你们猜怎么着?我用Python写了一段录制GIF的脚本,随时随地打开就能录,还是挺有用的。所以忍不住想给大伙分享一下,也当做一个学习Python上手的项目。
首先,我已经把代码和exe应用程序都打包好了,上传到了GitHub和
网盘(链接: https://pan.baidu.com/s/1AWd9uYrquuWIAKqz6ScV0A 提取码: gifs)。只需运行Python脚本或者像我这样懒一点直接点开应用程序,直接点击你要录制窗口的左上角和右下角,然后程序就开始自动录制了。想要停下来的时候,就按一下键盘左上角的“ESC”键来结束。耐心等一段时间,GIF动图就会保存到程序脚本的文件夹里,随时可以分享给朋友、家人或者同学同事。
接下来打开脚本,我来简单介绍一下这个小程序。首先,我是用现在很火的UV管理工具来创建项目的,所以也推荐大伙用UV来复刻和启动这个项目。想要了解UV的小伙伴,我会把教学链接放在下面。这里比如说,你就可以用uv sync来同步整个项目需要的所有库,不需要你一个个用pip install来安装了。说起来,这里我们会用到三个第三方的库:
- pyautogui(pip install pyautogui):可以用来截屏;
- PIL(pip install pillow):可以用来抓取屏幕实际像素;
- pynput(pip install pynput):可以监听键盘按键和鼠标点击;
import os
import time
import pyautogui
from PIL import ImageGrab
from pynput import keyboard
from pynput.mouse import Listener
output_file = "output.gif"
frame_duration = 0.2
stop_recording = False
window = {'x': 0, 'y': 0, 'width': 0, 'height': 0}
def on_click(x, y, button, pressed):
if pressed:
click_positions.append((x, y))
if len(click_positions) == 1:
print('请点击窗口右下角来完成选区。')
if len(click_positions) == 2:
return False
def get_two_click_coordinates():
global click_positions
click_positions = []
clicks = 0
print('请点击窗口左上角以开始选区。')
while clicks < 2:
with Listener(on_click=on_click) as listener:
listener.join()
clicks += 1
return click_positions
def calculate_rectangle_dimensions(coord1, coord2):
global window
width = abs(coord2[0] - coord1[0])
height = abs(coord2[1] - coord1[1])
window.update(x=int(coord1[0]), y=int(coord1[1]),
width=int(width), height=int(height))
return width, height
def on_press(key):
global stop_recording
if key == keyboard.Key.esc:
stop_recording = True
def record_gif(top_left, window, output_file, duration=0.1):
frames = []
print(f"录制中... 每帧间隔: {duration:.2f}s, 按 'ESC' 键结束录制。")
with keyboard.Listener(on_press=on_press) as listener:
while not stop_recording:
screenshot = pyautogui.screenshot(
region=(top_left[0], top_left[1], window['width'], window['height']))
frames.append(screenshot)
time.sleep(duration)
if os.path.exists(output_file):
print(f"警告:文件 '{output_file}' 已存在,将被覆盖。")
print(f"正在保存 GIF 到 {output_file}")
frames[0].save(
output_file,
save_all=True,
append_images=frames[1:],
duration=int(duration * 1000),
loop=0,
)
print("GIF 已保存。")
def main():
global window
coordinates = get_two_click_coordinates()
print(f"第一次点击: {coordinates[0]}, 第二次点击: {coordinates[1]}")
width, height = calculate_rectangle_dimensions(
coordinates[0], coordinates[1])
print(f"选区尺寸: 宽 = {width}, 高 = {height}")
virtual_screen_width, virtual_screen_height = pyautogui.size()
screenshot = ImageGrab.grab()
screen_width, screen_height = screenshot.size
pixel_ratio = int(screen_width / virtual_screen_width)
window.update(x=int(window['x'] * pixel_ratio), y=int(window['y'] * pixel_ratio),
width=int(window['width'] * pixel_ratio), height=int(window['height'] * pixel_ratio))
print(
f"位置: x={window['x']}, y={window['y']}, 宽={window['width']}, 高={window['height']}")
top_left = (window['x'], window['y'])
record_gif(top_left, window, output_file, frame_duration)
if __name__ == "__main__":
main()
然后是几个函数的功能:
- on_click函数会在你点鼠标的时候被触发。它是一个回调函数,被 pynput.mouse.Listener在监听时调用。用户第一次点击,录制窗口左上角的坐标被记录,用户第二次点击后,右下角坐标被记录,然后返回False告诉Listener:“监听结束,用户选好了”。
- get_two_click_coordinates函数的作用是调用监听器然后返回这两个点的坐标。首先启动监听器,让on_click()接管鼠标点击事件,两次点完后,它就把两个坐标作为一对返回。
- 咱们刚才不是点了两个位置嘛?这个函数就是用来根据那两个点算出你想要录的矩形区域有多大。然后把这些值填进window这个字典里,表示说“我要录这个区域”;最后它把宽和高也返回了,方便在后面打印出来看下尺寸。
- on_press函数专门监听你按的键。如果你按的是ESC键,那么就把stop_recording设置成True。这样主程序就知道“哎,用户想停了,我不录了”;
- record_gif函数是整个程序的核心。它用pyautogui.screenshot不断地截图,把每一帧都存在frames这个列表里。我们在循环里加了time.sleep函数,这样就不会太快截图,是用来控制“帧率”的。一旦用户按下ESC,整个循环也就停了。然后它就把所有帧合成一个GIF动图。
- 在main()函数里除了刚才介绍的记录两坐标位置和计算矩形区域的函数之外,这一段有点“黑科技”的意思,是为了处理高DPI屏幕,比如4K显示器下的截图区域可能对不上的问题。操作系统为了让文字和界面元素在高分辨率屏幕上不至于太小,会启用一种叫屏幕缩放(DPI Scaling) 的功能。pyautogui.size() 拿到的是逻辑分辨率(比如说1080p),ImageGrab拿到的是实际像素(比如说4K);如果两者不一样,说明你屏幕缩放了;所以我们用这个比值pixel_ratio来修正坐标,把录制区域的坐标和尺寸“拉伸”一下,确保录屏时不会有偏移或者缩放错误。最后,用我们之前讲过的record_gif(),让它开始真正录制画面,直到按下ESC停止。
就这么简单!用这个脚本,你就可以轻松录制屏幕上任意窗口,然后保存为GIF动图,分享给你的亲朋好友。你学会了吗?

Leave a comment