自动修改分辨率的脚本怎么写

wen 实用脚本 2

告别模糊与拉伸:手把手教你编写自动修改分辨率的脚本(Windows/macOS/Linux通用)


📖 目录导读

  1. 为什么你需要一个“自动改分辨率”脚本?(痛点与场景)
  2. 核心原理:操作系统如何控制分辨率?(通俗解释)
  3. 实战代码:三平台脚本拆解(Windows / macOS / Linux)
    • 1 Windows PowerShell 脚本(针对显卡与多显示器)
    • 2 macOS 使用 Swift 与 CoreGraphics(Apple Silicon 兼容)
    • 3 Linux 基于 xrandr 的 Bash 脚本(最灵活方案)
  4. 进阶技巧:如何让脚本“自动”判断最佳分辨率?(EDID 读取 + 逻辑判断)
  5. 常见问题与避坑指南(FAQ)
  6. 从脚本到生产力的最后一公里

为什么你需要一个“自动改分辨率”脚本?

你是否遇到过这样的场景:外接投影仪时,笔记本分辨率突然变成 800x600,字体糊成一片;或者远程桌面断开后,物理显示器分辨率被重置为默认值;又或者每天上班需要手动把 4K 显示器从 150% 缩放调回 100%

自动修改分辨率的脚本怎么写

手动点击“设置 > 系统 > 显示 > 高级显示设置”固然可行,但效率极低。一个精心编写的脚本,可以在 3 秒内完成分辨率切换,并且可以绑定到键盘快捷键、开机启动项,甚至根据当前连接的显示器 ID 自动切换,这不仅能提升工作效率,还能保护你的眼睛(避免长期使用错误缩放导致的视疲劳)。

核心原理:操作系统如何控制分辨率?

在动手写代码前,必须理解底层逻辑,分辨率并不是一个“粗暴的像素宽高”,它由三部分组成:

  • 像素时钟(Pixel Clock):决定显卡输出信号的频率。
  • 水平同步(H-Sync)垂直同步(V-Sync):定义扫描线时序。
  • 显示器的 EDID 数据:这相当于显示器的“身份证”,里面存储了它支持的所有有效分辨率、刷新率及像素格式。

修改分辨率的本质,是告诉显卡驱动“请按这个 EDID 参数模式输出信号”,操作系统本身不生产分辨率,它只是从显示器 EDID 中“读取”并“切换”。

明白了这一点,你的脚本其实是在做两件事:

  1. 枚举当前连接的显示器支持的模式。
  2. 发送指令给系统的显示服务,切换到目标模式。

实战代码:三平台脚本拆解

1 Windows PowerShell 脚本(针对多显示器)

Windows 下最稳定的方案是通过 WMI (Windows Management Instrumentation) 或调用 CIMWmiMonitorListedSupportedSourceModes 类,但更简单的方法是直接调用外置工具 QRes.exe 或使用 DisplayChanger,不过这里推荐纯 PowerShell 使用 Win32 API(代码较长,故简化为调用 .NET 方法):

# 保存为 set-resolution.ps1
Add-Type @"
using System;
using System.Runtime.InteropServices;
public class ResChanger {
    [DllImport("user32.dll")]
    public static extern int EnumDisplaySettings(string deviceName, int modeNum, ref DEVMODE devMode);
    [DllImport("user32.dll")]
    public static extern int ChangeDisplaySettings(ref DEVMODE devMode, int flags);
    [StructLayout(LayoutKind.Sequential)]
    public struct DEVMODE { ... } // 结构体略
}
"@
# 切换到 2560x1440 @ 60Hz
$mode = New-Object ResChanger+DEVMODE
$mode.dmSize = [System.Runtime.InteropServices.Marshal]::SizeOf($mode)
$mode.dmPelsWidth = 2560
$mode.dmPelsHeight = 1440
$mode.dmDisplayFrequency = 60
$mode.dmFields = 0x00080000 -bor 0x00040000 -bor 0x00010000 # 宽度+高度+频率
[ResChanger]::ChangeDisplaySettings([ref]$mode, 0)

注意:上述代码需填充完整的 DEVMODE 结构体,实战中建议用 EnumDisplaySettings 取出当前模式的完整结构,然后只修改宽高字段,避免黑屏。

2 macOS 使用 Swift 与 CoreGraphics

macOS 的显示管理由 CGDisplay 系列 API 控制,以下是命令行工具的 Swift 片段(通过 swift 命令直接运行):

import CoreGraphics
// 获取第一个在线显示器 ID
let displayID = CGMainDisplayID()
// 创建一个模式字典
let mode = CGDisplayCopyDisplayMode(displayID)!
let newMode = CGDisplayMode(dictionaryRepresentation: mode.dictionaryRepresentation()! as CFDictionary)
// 将宽度改为 1920,高度改为 1080
var pixelWidth = 1920
var pixelHeight = 1080
let options = [kCGDisplayChangeToMode: NSNumber(value: pixelWidth * 2)]  // Retina 缩放处理
// 实际需调用 CGDisplaySetDisplayMode(displayID, newMode)
print("请通过 swiftc 编译后运行,且需授权屏幕录制权限")

提示:macOS 的“缩放”逻辑与 Windows 不同,脚本需处理 Retina 的 pointpixel 换算,更简单的方法是直接使用 defaults write /Library/Preferences/com.apple.windowserver DisplayResolutionEnabled -bool YES 强制开启 UI 缩放选项。

3 Linux 基于 xrandr 的 Bash 脚本(最灵活)

Linux 下最主流的是 xrandr 命令,它可以直接查询、添加、修改分辨率:

#!/bin/bash
# 自动修改分辨率为 3840x2160@60
OUTPUT="DP-1"  # 通过 xrandr -q 查询你的输出接口名
WIDTH=3840
HEIGHT=2160
REFRESH=60
# 第一步:创建新的 mode(如果不存在)
if ! xrandr --query | grep -q "$WIDTH""x""$HEIGHT"; then
    MODELINE=$(cvt $WIDTH $HEIGHT $REFRESH | grep Modeline | cut -d' ' -f3-)
    xrandr --newmode "$WIDTH""x""$HEIGHT""_""$REFRESH" $MODELINE
fi
# 第二步:添加到输出口并应用
xrandr --addmode $OUTPUT "$WIDTH""x""$HEIGHT""_""$REFRESH"
xrandr --output $OUTPUT --mode "$WIDTH""x""$HEIGHT""_""$REFRESH" --rate $REFRESH

重点:加一句 xrandr -q | grep "connected primary" 可自动检测主屏幕,避免硬编码 DP-1


进阶技巧:如何让脚本“自动”判断最佳分辨率?

如果想实现“插入 1080p 投影仪自动切换,拔掉后恢复默认”,需要检测 EDID,Linux 下用 edid-decode 解析 /sys/class/drm/*/edid 文件,提取首个 EDID 块中的 dtiming,Windows 可用 Get-CimInstance -Namespace root\wmi -ClassName WmiMonitorID 获取厂商、产品码,然后匹配一个 switch case 逻辑。

简单逻辑示例:

# 检测当前连接的显示器型号
if xrandr --prop | grep -A 5 "DisplayPort-0" | grep -q "PANEL"; then
    xrandr --output eDP-1 --mode 2560x1600   # 内置屏
else
    xrandr --output eDP-1 --off --output HDMI-1 --mode 1920x1080
fi

常见问题与避坑指南(FAQ)

Q1:脚本一运行屏幕就黑屏,但没反应,怎么办? A:首先按 Ctrl+Alt+F2(Linux)或 Win+P(Windows)切换控制台,或重启进程,原因多半是模式参数不匹配(例如宽度正确但像素时钟超出显卡范围),请在脚本里加入超时回滚逻辑:尝试切换 5 秒后,如果用户没确认,自动恢复原分辨率(xrandr --output $OUTPUT --mode $OLD_MODE)。

Q2:外接显示器时,脚本找不到那个输出接口名(如 DP-1)? A:使用 xrandr --listmonitors 获取动态接口名,在脚本开头用正则动态提取,Windows 用 Get-CimInstance -ClassName WmiMonitorBasicDisplayParams 获取 Name

Q3:我的脚本需要开机自动运行,但提示权限不足? A:Windows 计划任务勾选“使用最高权限运行”;Linux 将脚本放入 /etc/xdg/autostart/ 并注意仅当桌面环境启动时运行(避免 tty 下报错)。

Q4:有没有“傻瓜式”的图形化脚本生成器? A:Windows 有 DisplayFusion 的配置文件导出,Linux 有 arandr(可视化配置后保存为 shell 脚本),但自己写 2 行代码能更精确控制逻辑。


从脚本到生产力的最后一公里

这篇文章教给你的不仅是命令,更是一种思考方式:任何重复性操作,都可以抽象成“枚举状态 → 匹配条件 → 切换动作”三段式脚本,写完脚本后,一定要做 dry-run 测试(先打印将执行的命令,不实际执行),并加上 set -e(Bash)或 $ErrorActionPreference=Stop(PowerShell)防止错误堆积。

你可以把脚本封装成一个带 GUI 下拉框 的小工具,或者挂载到全局快捷键(如 Ctrl+Alt+1 切换 1080p,Ctrl+Alt+2 切换 4K),当你的同事还在抱怨“今天分辨率又乱了”时,你只需按一个键,这就是技术的从容。

行动建议:今天先在你的设备上试试上述 Bash 或 PowerShell 代码,把打印 xrandr -q 输出这一步做好,你就成功了一半。

抱歉,评论功能暂时关闭!