You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

鼠标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()

关键说明

  1. 关闭鼠标加速:Windows默认的"提高指针精准度"会导致像素移动与鼠标硬件计数不成正比,必须关闭才能获取准确结果
  2. 参数配置:根据自己的显示器修改SCREEN_WIDTH_PX、SCREEN_HEIGHT_PX、SCREEN_DIAGONAL_IN,以及鼠标设定的SET_DPI
  3. 误差容忍:设置了5%的误差范围,避免因手动移动无法精准达到目标像素的问题

内容的提问来源于stack exchange,提问作者Chance D

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 12:23:14