鼠标DPI计算脚本问题:如何精准检测实际DPI与设定值的偏差?
鼠标DPI偏差检测脚本优化方案
问题背景
需要通过鼠标光标移动距离计算真实DPI,检测设定值(如900DPI)与实际值的偏差,避免人工测量误差。现有脚本无法实现专业DPI分析仪的两点测量法,计算结果不准确。
核心优化思路
- 实现两点测量逻辑:记录鼠标起始位置,当移动像素距离达到设定阈值(如1280px)时,自动计算真实DPI
- 修正屏幕PPI计算:确保像素与物理英寸的转换精准
- 增加操作指引:明确告知用户操作步骤,减少操作误差
- 过滤抖动干扰:忽略微小移动,只处理有效测量数据
- 直接输出偏差值:对比设定DPI,直观显示偏差
优化后完整脚本
import ctypes from pynput.mouse import Listener, Button import math # 配置参数 SET_DPI = 900 # 鼠标软件中设置的DPI值 TARGET_PX_DISTANCE = 1280 # 目标移动像素距离(推荐用屏幕宽度的一半) SCREEN_WIDTH_PX = 2560 SCREEN_HEIGHT_PX = 1440 SCREEN_DIAGONAL_IN = 27.9 # 显示器对角线物理尺寸(英寸) # 计算屏幕物理尺寸与PPI aspect_ratio = SCREEN_WIDTH_PX / SCREEN_HEIGHT_PX screen_width_in = (SCREEN_DIAGONAL_IN * aspect_ratio) / math.sqrt(aspect_ratio**2 + 1) screen_height_in = screen_width_in / aspect_ratio ppi_x = SCREEN_WIDTH_PX / screen_width_in # X轴每英寸像素数 ppi_y = SCREEN_HEIGHT_PX / screen_height_in # Y轴每英寸像素数 # 测量状态变量 start_pos = None is_measuring = False def calculate_real_dpi(move_px, ppi): """通过移动像素距离计算真实DPI""" if move_px == 0: return 0 # 移动的物理距离(英寸)= 像素距离 / 屏幕PPI move_in = move_px / ppi # 真实DPI = 鼠标移动计数(像素距离对应硬件计数,需关闭系统加速)/ 物理距离 return (move_px * SET_DPI) / TARGET_PX_DISTANCE def on_click(x, y, button, pressed): """处理鼠标点击,触发测量开始/结束""" global start_pos, is_measuring if button == Button.left: if pressed: if not is_measuring: start_pos = (x, y) is_measuring = True print(f"已记录起始位置,水平/垂直移动{TARGET_PX_DISTANCE}像素后再次点击左键完成测量") else: # 计算移动距离 move_px_x = abs(x - start_pos[0]) move_px_y = abs(y - start_pos[1]) if move_px_x >= TARGET_PX_DISTANCE * 0.95: # 允许5%误差范围 real_dpi_x = calculate_real_dpi(move_px_x, ppi_x) deviation_x = real_dpi_x - SET_DPI print("\n=== X轴测量结果 ===") print(f"实际移动像素: {move_px_x}px") print(f"设定DPI: {SET_DPI}") print(f"真实DPI: {real_dpi_x:.2f}") print(f"DPI偏差: {deviation_x:.2f} ({(deviation_x/SET_DPI)*100:.2f}%)") else: print(f"X轴移动距离不足,需至少{TARGET_PX_DISTANCE}px,当前仅{move_px_x}px") if move_px_y >= TARGET_PX_DISTANCE * 0.95: real_dpi_y = calculate_real_dpi(move_px_y, ppi_y) deviation_y = real_dpi_y - SET_DPI print("\n=== Y轴测量结果 ===") print(f"实际移动像素: {move_px_y}px") print(f"设定DPI: {SET_DPI}") print(f"真实DPI: {real_dpi_y:.2f}") print(f"DPI偏差: {deviation_y:.2f} ({(deviation_y/SET_DPI)*100:.2f}%)") else: print(f"Y轴移动距离不足,需至少{TARGET_PX_DISTANCE}px,当前仅{move_px_y}px") is_measuring = False start_pos = None def on_move(x, y): """实时显示当前移动进度""" if is_measuring and start_pos: current_move_x = abs(x - start_pos[0]) current_move_y = abs(y - start_pos[1]) print(f"\r当前移动进度 - X: {current_move_x}/{TARGET_PX_DISTANCE}px | Y: {current_move_y}/{TARGET_PX_DISTANCE}px", end="") if __name__ == "__main__": # 确保获取真实屏幕分辨率 ctypes.windll.user32.SetProcessDPIAware() print("=== 鼠标DPI偏差检测工具 ===") print("操作步骤:") print("1. 关闭鼠标加速(Windows控制面板-鼠标-指针选项-取消'提高指针精准度')") print("2. 点击左键记录起始位置") print("3. 水平/垂直移动鼠标至目标像素距离") print("4. 再次点击左键完成测量\n") with Listener(on_click=on_click, on_move=on_move) as listener: listener.join()
关键说明
- 关闭鼠标加速:Windows默认的"提高指针精准度"会导致像素移动与鼠标硬件计数不成正比,必须关闭才能获取准确结果
- 参数配置:根据自己的显示器修改
SCREEN_WIDTH_PX、SCREEN_HEIGHT_PX、SCREEN_DIAGONAL_IN,以及鼠标设定的SET_DPI - 误差容忍:设置了5%的误差范围,避免因手动移动无法精准达到目标像素的问题
内容的提问来源于stack exchange,提问作者Chance D
相关产品推荐
相关产品推荐

