鱼C论坛

 找回密码
 立即注册
12
返回列表 发新帖
楼主: 小甲鱼

[求贤令] 【开发中】求贤令000:开发一个截图程序

[复制链接]
 楼主| 发表于 2023-8-12 19:57:48 | 显示全部楼层
编程追风梦 发表于 2023-8-10 06:04
**** 作者被禁止或删除 内容自动屏蔽 ****

可以上B站哈~
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-8-13 05:49:19 | 显示全部楼层

嘻嘻
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-8-16 11:47:14 | 显示全部楼层
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-10-5 10:14:22 | 显示全部楼层
期待
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2023-10-15 15:46:56 | 显示全部楼层

等csp完了的
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-10-15 15:48:03 | 显示全部楼层

甲鱼哥要等好久
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-10-15 15:49:52 | 显示全部楼层

小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2025-5-4 10:27:57 | 显示全部楼层
本帖最后由 kbq1415 于 2025-5-4 10:35 编辑

Windows截屏程序

用的是Python
  1. import ctypes
  2. import sys
  3. import time

  4. # 定义Windows API所需的结构体和常量
  5. class BITMAPINFOHEADER(ctypes.Structure):
  6.     _fields_ = [
  7.         ('biSize', ctypes.c_ulong),
  8.         ('biWidth', ctypes.c_long),
  9.         ('biHeight', ctypes.c_long),
  10.         ('biPlanes', ctypes.c_ushort),
  11.         ('biBitCount', ctypes.c_ushort),
  12.         ('biCompression', ctypes.c_ulong),
  13.         ('biSizeImage', ctypes.c_ulong),
  14.         ('biXPelsPerMeter', ctypes.c_long),
  15.         ('biYPelsPerMeter', ctypes.c_long),
  16.         ('biClrUsed', ctypes.c_ulong),
  17.         ('biClrImportant', ctypes.c_ulong)
  18.     ]

  19. class BITMAPINFO(ctypes.Structure):
  20.     _fields_ = [
  21.         ('bmiHeader', BITMAPINFOHEADER),
  22.         ('bmiColors', ctypes.c_ulong * 3)
  23.     ]

  24. class POINT(ctypes.Structure):
  25.     _fields_ = [("x", ctypes.c_long), ("y", ctypes.c_long)]

  26. # GDI常量
  27. SRCCOPY = 0x00CC0020
  28. DIB_RGB_COLORS = 0
  29. WH_MOUSE_LL = 14
  30. WM_LBUTTONDOWN = 0x0201
  31. WM_LBUTTONUP = 0x0202
  32. WM_MOUSEMOVE = 0x0200

  33. # 全局变量存储选区坐标
  34. start_point = POINT()
  35. end_point = POINT()
  36. dragging = False

  37. # 鼠标钩子回调函数
  38. def low_level_mouse_handler(nCode, wParam, lParam):
  39.     global start_point, end_point, dragging
  40.     if nCode == 0:
  41.         event = wParam
  42.         mouse_data = ctypes.cast(lParam, ctypes.POINTER(MSLLHOOKSTRUCT)).contents
  43.         if event == WM_LBUTTONDOWN:
  44.             start_point.x = mouse_data.pt.x
  45.             start_point.y = mouse_data.pt.y
  46.             end_point.x = mouse_data.pt.x
  47.             end_point.y = mouse_data.pt.y
  48.             dragging = True
  49.         elif event == WM_MOUSEMOVE and dragging:
  50.             # 实时更新选区终点
  51.             end_point.x = mouse_data.pt.x
  52.             end_point.y = mouse_data.pt.y
  53.         elif event == WM_LBUTTONUP:
  54.             end_point.x = mouse_data.pt.x
  55.             end_point.y = mouse_data.pt.y
  56.             dragging = False
  57.             return 1  # 终止钩子
  58.     return ctypes.windll.user32.CallNextHookEx(None, nCode, wParam, lParam)

  59. def select_region():
  60.     """通过鼠标交互选择屏幕区域"""
  61.     print("请按住鼠标左键拖拽选择区域,释放左键完成选择")
  62.    
  63.     # 安装鼠标钩子
  64.     hook_proc = ctypes.WINFUNCTYPE(ctypes.c_int, ctypes.c_int, ctypes.c_int, ctypes.POINTER(ctypes.c_void_p))(low_level_mouse_handler)
  65.     hook = ctypes.windll.user32.SetWindowsHookExA(WH_MOUSE_LL, hook_proc, None, 0)
  66.    
  67.     # 消息循环
  68.     msg = ctypes.wintypes.MSG()
  69.     while ctypes.windll.user32.GetMessageA(ctypes.byref(msg), None, 0, 0) != 0:
  70.         if not dragging:
  71.             break
  72.         ctypes.windll.user32.TranslateMessage(ctypes.byref(msg))
  73.         ctypes.windll.user32.DispatchMessageA(ctypes.byref(msg))
  74.    
  75.     # 卸载钩子
  76.     ctypes.windll.user32.UnhookWindowsHookEx(hook)
  77.    
  78.     # 规范坐标
  79.     x1 = min(start_point.x, end_point.x)
  80.     y1 = min(start_point.y, end_point.y)
  81.     x2 = max(start_point.x, end_point.x)
  82.     y2 = max(start_point.y, end_point.y)
  83.     return (x1, y1, x2, y2)

  84. def take_screenshot(x1=0, y1=0, x2=None, y2=None, filename='screenshot.bmp'):
  85.     """
  86.     执行屏幕截图
  87.     :param x1: 区域左上角X坐标
  88.     :param y1: 区域左上角Y坐标
  89.     :param x2: 区域右下角X坐标(None表示屏幕右边缘)
  90.     :param y2: 区域右下角Y坐标(None表示屏幕下边缘)
  91.     :param filename: 输出文件名
  92.     """
  93.     user32 = ctypes.windll.user32
  94.     gdi32 = ctypes.windll.gdi32
  95.    
  96.     # 获取屏幕尺寸
  97.     if x2 is None: x2 = user32.GetSystemMetrics(0)
  98.     if y2 is None: y2 = user32.GetSystemMetrics(1)
  99.     width = x2 - x1
  100.     height = y2 - y1
  101.    
  102.     # 设备上下文操作
  103.     hdc = user32.GetDC(None)
  104.     memdc = gdi32.CreateCompatibleDC(hdc)
  105.     bmp = gdi32.CreateCompatibleBitmap(hdc, width, height)
  106.     old_bmp = gdi32.SelectObject(memdc, bmp)
  107.    
  108.     # 复制屏幕区域
  109.     gdi32.BitBlt(memdc, 0, 0, width, height, hdc, x1, y1, SRCCOPY)
  110.    
  111.     # 准备位图信息结构
  112.     bmi = BITMAPINFO()
  113.     bmi.bmiHeader.biSize = ctypes.sizeof(BITMAPINFOHEADER)
  114.     bmi.bmiHeader.biWidth = width
  115.     bmi.bmiHeader.biHeight = -height  # 从上到下
  116.     bmi.bmiHeader.biPlanes = 1
  117.     bmi.bmiHeader.biBitCount = 24
  118.     bmi.bmiHeader.biCompression = 0
  119.    
  120.     # 获取位图数据
  121.     stride = ((width * 3 + 3) // 4) * 4
  122.     buffer_size = stride * height
  123.     buffer = ctypes.create_string_buffer(buffer_size)
  124.     gdi32.GetDIBits(hdc, bmp, 0, height, buffer, ctypes.byref(bmi), DIB_RGB_COLORS)
  125.    
  126.     # 构建BMP文件
  127.     file_header = bytearray(b'BM')
  128.     file_header.extend((14 + 40 + buffer_size).to_bytes(4, 'little'))
  129.     file_header.extend(bytes(4))
  130.     file_header.extend((14 + 40).to_bytes(4, 'little'))
  131.    
  132.     info_header = bytearray()
  133.     info_header.extend(bmi.bmiHeader.biSize.to_bytes(4, 'little'))
  134.     info_header.extend(width.to_bytes(4, 'little', signed=True))
  135.     info_header.extend((-height).to_bytes(4, 'little', signed=True))
  136.     info_header.extend(bmi.bmiHeader.biPlanes.to_bytes(2, 'little'))
  137.     info_header.extend(bmi.bmiHeader.biBitCount.to_bytes(2, 'little'))
  138.     info_header.extend(bmi.bmiHeader.biCompression.to_bytes(4, 'little'))
  139.     info_header.extend((stride * height).to_bytes(4, 'little'))
  140.     info_header.extend(bytes(16))
  141.    
  142.     with open(filename, 'wb') as f:
  143.         f.write(file_header)
  144.         f.write(info_header)
  145.         f.write(buffer)
  146.    
  147.     # 清理资源
  148.     gdi32.SelectObject(memdc, old_bmp)
  149.    
复制代码


小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2025-5-4 10:37:43 | 显示全部楼层
做了一个简单的Windows截屏程序
用Python。
  1. import ctypes
  2. import sys
  3. import time

  4. # 定义Windows API所需的结构体和常量
  5. class BITMAPINFOHEADER(ctypes.Structure):
  6.     _fields_ = [
  7.         ('biSize', ctypes.c_ulong),
  8.         ('biWidth', ctypes.c_long),
  9.         ('biHeight', ctypes.c_long),
  10.         ('biPlanes', ctypes.c_ushort),
  11.         ('biBitCount', ctypes.c_ushort),
  12.         ('biCompression', ctypes.c_ulong),
  13.         ('biSizeImage', ctypes.c_ulong),
  14.         ('biXPelsPerMeter', ctypes.c_long),
  15.         ('biYPelsPerMeter', ctypes.c_long),
  16.         ('biClrUsed', ctypes.c_ulong),
  17.         ('biClrImportant', ctypes.c_ulong)
  18.     ]

  19. class BITMAPINFO(ctypes.Structure):
  20.     _fields_ = [
  21.         ('bmiHeader', BITMAPINFOHEADER),
  22.         ('bmiColors', ctypes.c_ulong * 3)
  23.     ]

  24. class POINT(ctypes.Structure):
  25.     _fields_ = [("x", ctypes.c_long), ("y", ctypes.c_long)]

  26. # GDI常量
  27. SRCCOPY = 0x00CC0020
  28. DIB_RGB_COLORS = 0
  29. WH_MOUSE_LL = 14
  30. WM_LBUTTONDOWN = 0x0201
  31. WM_LBUTTONUP = 0x0202
  32. WM_MOUSEMOVE = 0x0200

  33. # 全局变量存储选区坐标
  34. start_point = POINT()
  35. end_point = POINT()
  36. dragging = False

  37. # 鼠标钩子回调函数
  38. def low_level_mouse_handler(nCode, wParam, lParam):
  39.     global start_point, end_point, dragging
  40.     if nCode == 0:
  41.         event = wParam
  42.         mouse_data = ctypes.cast(lParam, ctypes.POINTER(MSLLHOOKSTRUCT)).contents
  43.         if event == WM_LBUTTONDOWN:
  44.             start_point.x = mouse_data.pt.x
  45.             start_point.y = mouse_data.pt.y
  46.             end_point.x = mouse_data.pt.x
  47.             end_point.y = mouse_data.pt.y
  48.             dragging = True
  49.         elif event == WM_MOUSEMOVE and dragging:
  50.             # 实时更新选区终点
  51.             end_point.x = mouse_data.pt.x
  52.             end_point.y = mouse_data.pt.y
  53.         elif event == WM_LBUTTONUP:
  54.             end_point.x = mouse_data.pt.x
  55.             end_point.y = mouse_data.pt.y
  56.             dragging = False
  57.             return 1  # 终止钩子
  58.     return ctypes.windll.user32.CallNextHookEx(None, nCode, wParam, lParam)

  59. def select_region():
  60.     """通过鼠标交互选择屏幕区域"""
  61.     print("请按住鼠标左键拖拽选择区域,释放左键完成选择")
  62.    
  63.     # 安装鼠标钩子
  64.     hook_proc = ctypes.WINFUNCTYPE(ctypes.c_int, ctypes.c_int, ctypes.c_int, ctypes.POINTER(ctypes.c_void_p))(low_level_mouse_handler)
  65.     hook = ctypes.windll.user32.SetWindowsHookExA(WH_MOUSE_LL, hook_proc, None, 0)
  66.    
  67.     # 消息循环
  68.     msg = ctypes.wintypes.MSG()
  69.     while ctypes.windll.user32.GetMessageA(ctypes.byref(msg), None, 0, 0) != 0:
  70.         if not dragging:
  71.             break
  72.         ctypes.windll.user32.TranslateMessage(ctypes.byref(msg))
  73.         ctypes.windll.user32.DispatchMessageA(ctypes.byref(msg))
  74.    
  75.     # 卸载钩子
  76.     ctypes.windll.user32.UnhookWindowsHookEx(hook)
  77.    
  78.     # 规范坐标
  79.     x1 = min(start_point.x, end_point.x)
  80.     y1 = min(start_point.y, end_point.y)
  81.     x2 = max(start_point.x, end_point.x)
  82.     y2 = max(start_point.y, end_point.y)
  83.     return (x1, y1, x2, y2)

  84. def take_screenshot(x1=0, y1=0, x2=None, y2=None, filename='screenshot.bmp'):
  85.     """
  86.     执行屏幕截图
  87.     :param x1: 区域左上角X坐标
  88.     :param y1: 区域左上角Y坐标
  89.     :param x2: 区域右下角X坐标(None表示屏幕右边缘)
  90.     :param y2: 区域右下角Y坐标(None表示屏幕下边缘)
  91.     :param filename: 输出文件名
  92.     """
  93.     user32 = ctypes.windll.user32
  94.     gdi32 = ctypes.windll.gdi32
  95.    
  96.     # 获取屏幕尺寸
  97.     if x2 is None: x2 = user32.GetSystemMetrics(0)
  98.     if y2 is None: y2 = user32.GetSystemMetrics(1)
  99.     width = x2 - x1
  100.     height = y2 - y1
  101.    
  102.     # 设备上下文操作
  103.     hdc = user32.GetDC(None)
  104.     memdc = gdi32.CreateCompatibleDC(hdc)
  105.     bmp = gdi32.CreateCompatibleBitmap(hdc, width, height)
  106.     old_bmp = gdi32.SelectObject(memdc, bmp)
  107.    
  108.     # 复制屏幕区域
  109.     gdi32.BitBlt(memdc, 0, 0, width, height, hdc, x1, y1, SRCCOPY)
  110.    
  111.     # 准备位图信息结构
  112.     bmi = BITMAPINFO()
  113.     bmi.bmiHeader.biSize = ctypes.sizeof(BITMAPINFOHEADER)
  114.     bmi.bmiHeader.biWidth = width
  115.     bmi.bmiHeader.biHeight = -height  # 从上到下
  116.     bmi.bmiHeader.biPlanes = 1
  117.     bmi.bmiHeader.biBitCount = 24
  118.     bmi.bmiHeader.biCompression = 0
  119.    
  120.     # 获取位图数据
  121.     stride = ((width * 3 + 3) // 4) * 4
  122.     buffer_size = stride * height
  123.     buffer = ctypes.create_string_buffer(buffer_size)
  124.     gdi32.GetDIBits(hdc, bmp, 0, height, buffer, ctypes.byref(bmi), DIB_RGB_COLORS)
  125.    
  126.     # 构建BMP文件
  127.     file_header = bytearray(b'BM')
  128.     file_header.extend((14 + 40 + buffer_size).to_bytes(4, 'little'))
  129.     file_header.extend(bytes(4))
  130.     file_header.extend((14 + 40).to_bytes(4, 'little'))
  131.    
  132.     info_header = bytearray()
  133.     info_header.extend(bmi.bmiHeader.biSize.to_bytes(4, 'little'))
  134.     info_header.extend(width.to_bytes(4, 'little', signed=True))
  135.     info_header.extend((-height).to_bytes(4, 'little', signed=True))
  136.     info_header.extend(bmi.bmiHeader.biPlanes.to_bytes(2, 'little'))
  137.     info_header.extend(bmi.bmiHeader.biBitCount.to_bytes(2, 'little'))
  138.     info_header.extend(bmi.bmiHeader.biCompression.to_bytes(4, 'little'))
  139.     info_header.extend((stride * height).to_bytes(4, 'little'))
  140.     info_header.extend(bytes(16))
  141.    
  142.     with open(filename, 'wb') as f:
  143.         f.write(file_header)
  144.         f.write(info_header)
  145.         f.write(buffer)
  146.    
  147.     # 清理资源
  148.     gdi32.SelectObject(memdc, old_bmp)
  149.    
复制代码

他可以全屏、选择尺寸、滚动截屏
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-5-16 05:07

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表