折腾启动盘这件事,一旦上手就很难停下来。Ventoy 出现之后,我把抽屉里那几只反复格式化的 U 盘全清了——一个盘扔进去几十个镜像,开机直接选,省下来的时间够我泡两壶茶。但用久了总有个别扭的地方:功能是真好用,界面是真朴素,灰底白字往那一杵,跟我在别处精心调过的桌面完全不是一个画风。后来我才认真去翻文档,发现Ventoy 启动主题这套东西其实一直是开放的,底层走的就是 grub2 的主题体系,能改背景、能换字体、能给每个镜像配图标、能调菜单的坐标和配色,折腾空间比我最初以为的大得多。
这篇东西适合两类人看:一类是纯粹想让自己的启动盘好看点、拿出去不丢人的;另一类是想把启动菜单做成"能给同事直接用"的程度,比如菜单项写成中文别名、系统盘和工作盘用不同图标区分开。前者看完前三节基本就能动手,后者建议把配置那节和排查那节都过一遍。我下面讲的东西,都是我自己在几台机器、几种分辨率上反复试出来的,踩过的坑会明确标出来,参数能算的我会把算法写清楚,你照着抄就行。
1. 先搞清楚 Ventoy 主题到底改的是什么
1.1 启动链路与主题的生效位置
很多人一上来就去找"皮肤包",下载一个压缩包往 U 盘里一解压,重启发现没反应,然后就卡住了。问题出在没搞明白这条链路:机器通电 → 固件(UEFI 或传统 BIOS)→ 引导 Ventoy 的引导程序 → 加载 grub2 → grub2 读取配置 → 渲染菜单。主题只在最后一步生效,它本质上是 grub2 的一个渲染配置文件,不是 Ventoy 自己发明的格式。
理解了这一点,很多问题就自解了。比如"为什么我的主题在 A 机器上正常、在 B 机器上错位",因为 A 机器支持你设定的分辨率、B 机器不支持,grub2 回退到了低分辨率,而你的背景图是按高分辨率画的,自然错位。再比如"为什么图标不显示",因为图标是 grub2 的boot_menu组件功能,文本模式菜单下这套组件根本不参与渲染。
Ventoy 在这条链路上做的事情,是在 grub2 启动后动态生成菜单项(每个镜像一个条目),然后把渲染权交给主题文件。所以主题能控制"长什么样",但控制不了"有哪些项"——菜单项的数量、顺序、名字,是 Ventoy 扫描出来的,你只能通过别名插件去改显示名,不能凭空造一个不存在的条目。
1.2 三种菜单形态:文本、默认图形、自定义主题
Ventoy 的菜单其实有三种形态,很多人只知道前两种。
第一种是纯文本模式,黑底白字,跟早期的引导菜单一样,没有任何图形元素。这种模式下主题完全不生效,因为根本没走图形终端。
第二种是Ventoy 自带的图形菜单,这也是大多数人第一次见到的样子——有背景、有边框、有条目高亮,看起来"能用但不好看"。它其实是 Ventoy 内置的一套主题,位置在程序内部,你改不了。
第三种就是自定义主题,你提供一个theme.txt和配套资源,Ventoy 转而加载你的配置。触发条件是在配置文件里把主题路径指过去,同时把显示模式切成图形模式。这一步没做对,你放再多素材也是白搭。
注意:这三种形态是互斥的,同一时刻只有一种生效。所以排查"主题没反应"时,第一个要确认的就是当前到底跑在哪种形态下,别急着怀疑素材。
1.3 值不值得折腾:收益与代价的权衡
先说收益。最直接的是辨识度,一个盘里塞了二三十个镜像,纯文本列表找起来眼睛疼,配上图标和中文别名之后,扫一眼就能定位。其次是信息密度,你可以在菜单上放标题、放提示语、放倒计时进度条,甚至可以按用途把系统盘、维护盘、试验盘分区显示。第三是拿得出手,给同事做个"开箱即用"的维护盘,界面整洁一点,对方上手成本会低很多。
再说代价。分辨率适配是最大的坑,你按 1920×1080 做的主题,插到一台只支持 1024×768 的老机器上,要么错位要么花屏。字体也有成本,想要中文显示就得用带中文字形的字体转成 grub2 格式,一个字体文件动辄几 MB,而且字号越大文件越大。还有调试成本,主题改一次就得重启一次看效果,没有热重载。
我的建议是:如果你只用一两台固定机器,做一套精准适配的主题非常值;如果你这个盘是要到处插的"万能盘",那就老老实实用纯色背景加百分比布局,牺牲一点视觉效果换兼容性,别追求满屏背景图。
2. 主题目录怎么搭:文件结构一次说清
2.1 分区定位与目录约定
Ventoy 装好之后,U 盘上会有两个分区:一个是放镜像的数据分区,一个是 Ventoy 自己的引导分区(通常在磁盘末尾,容量很小,平时看不到)。主题文件要放在数据分区上,也就是你平时往里拖镜像的那个分区。
目录位置有约定俗成的规矩:数据分区根目录下的ventoy文件夹是 Ventoy 的配置区,里面通常有ventoy.json(主配置)和theme文件夹(主题存放处)。我习惯在theme下再建一层以主题名命名的子目录,比如theme/dark-blue/,这样以后想换风格,直接改配置指向另一个目录就行,两套素材互不干扰。
数据分区根目录/ ├── ISO/ 镜像存放目录(自己建) ├── ventoy/ │ ├── ventoy.json 主配置文件 │ └── theme/ │ └── dark-blue/ 一套主题一个目录 │ ├── theme.txt 必需,主题描述文件 │ ├── background.png 背景图 │ ├── icons/ 图标目录 │ └── fonts/ 字体目录路径大小写这件事要留个心眼。数据分区如果格式化成 exFAT,理论上不区分大小写,但 grub2 解析路径时是按字符串匹配的,配置里写Theme.txt、实际文件叫theme.txt,在某些版本上就会找不到。统一全小写是最省事的做法,我到现在都保持这个习惯。
2.2 最小可用主题清单
想先跑通再美化,可以只准备三个文件:theme.txt、一张背景图、一个字体文件。theme.txt里只写最基本的几行,能出画面就算成功,然后再一项项往上加。这种"最小可运行"的思路比一次性写满配置要靠谱得多,出问题时你永远知道是刚加的那一行出的错。
最小版本大概长这样:
desktop-image: "background.png" desktop-color: "#0b1020" + boot_menu { left = 10% top = 25% width = 80% height = 60% item_height = 30 item_padding = 6 item_font = "ThemeFont Regular 20" item_color = "#c8d4e8" selected_item_color = "#ffffff" }三行全局配置加一个组件块,就这么点东西。背景图用纯色也行,desktop-color兜底,图片路径写错也不会黑屏。字体名如果对不上,grub2 会回退到内置字体,画面照样出得来,只是字丑。这种设计对新手很友好,先看见东西,再谈精致。
2.3 背景图、图标、字体的格式要求
背景图这块,grub2 能读 PNG,也能读 JPEG(需要相应模块,Ventoy 一般内置了)。PNG 是最稳的选择,尤其是用索引色压缩过的 PNG,体积能压到几百 KB,加载快。尺寸必须和你设定的分辨率严格一致,1920×1080 就是 1920×1080,别拿个 2560×1440 的图让它缩,grub2 不会帮你做等比缩放,只会硬拉伸或者裁切。
图标的要求更明确:必须是正方形或者接近正方形,格式是 PNG,带透明通道。grub2 会按主题里写的icon_width和icon_height去缩放,但缩放质量一般,所以源图最好就直接做成目标尺寸,比如你要 32×32,就别塞 256×256 进去。图标文件名就是 class 名,这点后面讲配置时会细说。
字体是最容易被低估的一环。grub2 不认 TTF、不认 OTF,只认自己的一种位图字体格式(后缀.pf2)。转换工具是grub-mkfont,Linux 下装 grub 相关包就有,Windows 下可以用 WSL 或者预编译好的工具包。转换命令后面实战那节会给完整版,这里先记住一个关键点:中文字体转出来的 pf2 会很大,因为每个汉字都是独立的字形数据,几万个字全塞进去,十几 MB 很正常。所以如果菜单里中文不多,可以考虑用子集化工具先裁掉不用的字,能省一大半体积。
3. theme.txt 核心参数逐个拆解
3.1 全局段落:分辨率之外还有哪些开关
theme.txt的语法很像 CSS 的简化版,前半部分是全局属性,后半部分是以+开头的组件块。全局区里最常改的几个:
| 属性 | 作用 | 常见取值 |
|---|---|---|
desktop-image | 背景图相对路径 | "background.png" |
desktop-color | 图片缺失时的兜底底色 | "#0b1020" |
title-text | 顶部标题文字 | "启动菜单" |
terminal-font | 进入命令行时的字体 | "ThemeFont Regular 16" |
terminal-box | 命令行窗口边框贴图 | 九宫格切片名 |
title-text这个属性容易被忽略,但它其实是唯一一个不需要组件块就能显示文字的地方,很多主题会把它当"标题栏"用。要注意它显示在屏幕最上方,位置固定,不能调坐标,所以背景图顶部最好留一条留白或者深色带,不然文字直接压在花哨图案上会看不清。
terminal-box是给 grub2 的交互命令行用的边框贴图,正常情况下你根本看不到它,只有在启动失败掉进命令行时才出现。可以不管,也可以顺手配一下——万一哪天真掉进去了,有个能看清的窗口总比满屏串色强。
3.2 boot_menu 组件:菜单项的全部视觉规则
boot_menu是整个主题的核心,菜单长什么样全在这块。
+ boot_menu { left = 12% top = 28% width = 76% height = 56% item_font = "ThemeFont Regular 20" item_color = "#c8d4e8" selected_item_color = "#ffffff" selected_item_pixmap_style = "select_*.png" item_height = 34 item_padding = 8 item_spacing = 4 icon_width = 28 icon_height = 28 item_icon_space = 10 scrollbar = true scrollbar_width = 8 }坐标和尺寸用百分比是相对屏幕的,用纯数字是绝对像素。百分比和像素混用是可以的,但混用之后你要清楚每个值的参照系不同,改分辨率时只有百分比那部分会跟着变。
item_height和字体大小的关系是新手最容易翻车的地方。经验公式是:item_height ≥ 字号 × 1.3 + item_padding × 2。比如字号 20,padding 8,那 item_height 至少要 42 才不挤。我见过太多主题把字号设成 24、item_height 设成 26,结果文字上下被裁掉一半。宁可留白多,不要挤。
selected_item_pixmap_style是高亮条的贴图前缀,*会被替换成九宫格的方位后缀。所谓九宫格,就是把一个矩形拆成九个部件,四角固定、四边拉伸、中心填充,这样不管条目多宽都能保持圆角不变形。需要准备的文件名清单如下:
select_c.png中心填充select_n.pngselect_s.png上下边select_w.pngselect_e.png左右边select_nw.pngselect_ne.pngselect_sw.pngselect_se.png四角
少一个部件,那一条边就渲染不出来,表现是高亮条缺一块或者干脆不显示。想省事也可以不用贴图,直接靠selected_item_color变色,效果朴素但绝对不会出错。
3.3 label 与 progress_bar:把菜单做得更像"界面"
label组件用来放置静态文字,可以放多处,每处独立设坐标、字体、颜色、对齐方式。它是把"启动菜单"这种冷冰冰的列表变成"引导界面"的关键——顶部放个大标题,底部放一行使用提示,中间是菜单,视觉层次立刻就出来了。
+ label { left = 0 top = 6% width = 100% height = 60 align = "center" color = "#e8eefc" font = "ThemeFont Regular 32" text = "系统维护盘" } + label { left = 0 top = 92% width = 100% height = 30 align = "center" color = "#6b7a99" font = "ThemeFont Regular 14" text = "方向键选择 回车启动 ESC 返回" }progress_bar组件一般用来做启动倒计时。Ventoy 的倒计时进度条有固定 id,绑定方式是在组件里写id = "__timeout__",这样它就会自动跟倒计时联动,不需要你额外做什么。
+ progress_bar { id = "__timeout__" left = 20% top = 86% width = 60% height = 14 show_text = true font = "ThemeFont Regular 14" text_color = "#9fb0cc" bar_style = "bar_*.png" highlight_style = "bar_hl_*.png" }进度条的贴图同样是九宫格切片,bar_*是底槽,bar_hl_*是已填充部分。不配贴图也能显示,会用默认的纯色块,功能上完全够用,只是不那么精致。
3.4 坐标单位的选择会直接影响兼容性
这一节单独拎出来讲,因为它决定了你的主题是"只能自己用"还是"插哪都能看"。
全部用百分比的好处是自适应,1920×1080 上菜单在屏幕中间偏下,1024×768 上还是中间偏下,只是元素变小、字号相对变大,视觉上会有点挤但不至于错位。全部用像素的好处是精准,你能把每个元素卡在背景图的指定位置,但换分辨率就全乱。
我的做法是菜单区和文字用百分比,元素尺寸用像素,背景图配一张低分辨率的兜底版。具体说,lefttopwidthheight全用百分比,item_heighticon_width这类用像素,背景图准备两张,1920×1080 和 1024×768 各一张,靠两套主题目录切换。听起来麻烦,但实际上做一次就一劳永逸,比每次插到新机器上重新调要省事。
还有一个隐藏细节:百分比是相对图形终端屏幕算的,而图形终端的分辨率由配置文件里的分辨率设定决定。如果设定的分辨率机器不支持,grub2 回退到别的模式,百分比会跟着新分辨率重新算,但你的背景图还是老尺寸,这时候就会出现"元素位置对但背景被拉花"的情况。所以分辨率设定和背景图尺寸必须锁死成一对,这是硬约束。
4. ventoy.json 配置:让主题真正挂上去
4.1 theme 插件字段逐个说明
配置文件是数据分区下的ventoy/ventoy.json,所有插件都写在同一个 JSON 对象里。主题相关的配置叫 theme 插件,写法如下:
{ "theme": { "file": "/ventoy/theme/dark-blue/theme.txt", "gfxmode": "1920x1080", "display_mode": "GUI", "ventoy_left": "5%", "ventoy_top": "95%", "ventoy_color": "#4a5a7a" } }file是主题描述文件的绝对路径,/开头表示数据分区根目录。这个路径写错是最常见的"主题不生效"原因,多一层少一层目录都会失败,而且失败时没有任何显式报错,只会安静地退回默认样子。我的习惯是先把路径复制粘贴到文件管理器地址栏验证一遍,再写进配置。
gfxmode就是分辨率,格式是宽x小写x高,比如1920x1080。这里有个坑:不能写成1920X1080,大写 X 会导致解析失败。
display_mode有两个取值,GUI是图形菜单,CLI是文本菜单。想让主题生效,这里必须是GUI。很多人下载了主题包,只改了file没改这里,结果一直是文本模式,素材再好也看不到。
ventoy_left、ventoy_top、ventoy_color这三个是控制左下角那个版本信息水印的。默认位置在左下角,颜色偏暗,如果你背景图在那个位置有重要图案,可以把水印挪到右上角或者干脆调成和背景接近的颜色让它"隐形"。这个细节文档里写得比较简略,但实际很有用——我见过有人为了躲这个水印,硬生生把背景图右下角挖空一块,其实改个坐标就完事了。
4.2 control 插件里几个影响外观的开关
control插件看起来是控制行为的,但其中好几个选项会直接影响菜单的呈现效果。
{ "control": [ { "VTOY_DEFAULT_MENU_MODE": "0" }, { "VTOY_MENU_TIMEOUT": "10" }, { "VTOY_FILT_DOT_UNDERSCORE_FILE": "1" } ] }VTOY_DEFAULT_MENU_MODE决定菜单是列表视图还是树形视图。列表视图是一长条,所有镜像平铺;树形视图按目录分层,适合镜像特别多、自己分了子目录的情况。树形视图的问题是层级一深,操作就变繁琐,上下左右四个键都得用。我个人偏好列表视图配中文别名,简单直接。
VTOY_MENU_TIMEOUT是自动启动的倒计时秒数,配合前面说的进度条组件,就能做出"十秒后自动进入默认系统"的效果。这个值设多少看场景,维护盘建议设长一点甚至不设,因为维护盘经常需要现场挑系统,倒计时走完自动进了默认项反而耽误事。
VTOY_FILT_DOT_UNDERSCORE_FILE是过滤掉以点或下划线开头的文件。这个开关和主题无关,但很实用——macOS 往 U 盘里拷东西会生成一堆._开头的隐藏文件,不过滤的话菜单里会凭空多出一堆看不懂的条目,视觉上直接崩掉。
4.3 menu_alias 与 menu_class:让菜单"看得懂"
这两个插件是提升可读性的主力。
menu_alias用来给镜像改显示名。原始文件名通常是xxx-22.04-desktop-amd64.iso这种,菜单里显示这个谁也看不出是什么。改成中文别名之后一目了然:
{ "menu_alias": [ { "image": "/ISO/example-linux.iso", "alias": "办公系统 稳定版" }, { "image": "/ISO/toolbox.iso", "alias": "硬件检测工具集" }, { "image": "/ISO/win-install.iso", "alias": "系统安装盘" } ] }image是镜像的完整路径,必须和数据分区上的实际路径完全一致。alias支持中文,但前提是你的主题字体包含中文字形,否则会显示成方块或者空白——这一点我在排查那节还会再提。
menu_class用来给镜像指定图标类别。grub2 渲染每个菜单项时会去找对应的图标文件,找的依据就是 class。Ventoy 自身会根据文件名做一些猜测,但猜得不一定准,这时候就手动指定:
{ "menu_class": [ { "key": "toolbox", "class": "tool" }, { "key": "win-install", "class": "windows" }, { "key": "example-linux", "class": "linux" } ] }key是文件名里的关键字,匹配上了就把这个镜像归到对应 class。class 名要和icons目录下的 png 文件名一致,比如class是tool,那就要有icons/tool.png。没有匹配到任何 class 的条目,会去找icons/unknown.png兜底,所以这个文件建议一定要放,不然菜单里会出现图标位置空一块的观感。
| 常用 class | 对应图标文件 | 适用场景 |
|---|---|---|
linux | icons/linux.png | 各类 Linux 发行版镜像 |
windows | icons/windows.png | 系统安装镜像 |
tool | icons/tool.png | 检测、分区、备份类工具 |
pe | icons/pe.png | 轻量维护环境 |
unknown | icons/unknown.png | 兜底,建议必放 |
5. 实战:从零做一套 1920×1080 主题
5.1 分辨率决策与背景图制作
先定分辨率。这一步不能拍脑袋,得看你主要在哪类机器上用。近十年的机器基本都支持 1920×1080,但如果是给老设备做维护盘,1024×768 更保险。折中方案是设成 1366×768,兼容性和清晰度都还过得去。
定好之后做背景图。我用的是深色渐变加一点几何装饰,深色是因为启动菜单的文字默认浅色,深底浅字对比度高,看着不累。做图工具无所谓,导出时必须严格按目标分辨率,PNG 格式,色彩数尽量压到 256 色以内。
# 用 ImageMagick 生成一张 1920x1080 的深色渐变底图 convert -size 1920x1080 \ gradient:'#0b1020-#1b2a4a' \ -fill '#12203a' -draw 'rectangle 0,140 1920,145' \ -quality 95 background.png背景图上有几个位置要提前留白:顶部大约 8% 的高度留给标题,中间 28% 到 84% 的区域留给菜单,底部 8% 留给提示语和进度条。这和前面给的坐标是配套的,你要是调了坐标,留白也得跟着改。先定布局再做图,别先做图再迁就坐标,后者能把人逼疯。
5.2 字体转换与字号计算
字体转换是整套流程里技术含量最高的一步。命令本身不复杂:
# 把 TTF 转成 grub2 能识别的 pf2 位图字体 grub-mkfont -s 20 \ -n "ThemeFont Regular 20" \ -o theme-font-20.pf2 \ SourceHanSans-Regular.ttf-s是字号,-n是字体在主题文件里被引用时的名字,-o是输出文件名。这里的-n极其关键——theme.txt里的item_font写的不是文件名,而是这个名字。名字对不上,字体就加载不了,grub2 会安静地回退到默认字体。
名字的格式惯例是"家族名 样式 字号",中间用空格分隔。我一般直接写成ThemeFont Regular 20这种带字号的形式,因为同一个字体不同字号要转成不同的 pf2 文件,名字里带上字号能避免混淆。
字号怎么定?有个基于分辨率的估算方法:字号 ≈ 屏幕高度 ÷ 40。1080 除以 40 约等于 27,考虑到菜单还要放图标,实际用 20 到 24 比较合适。768 的话,768 ÷ 40 约等于 19,用 16 到 18。这个公式不是绝对的,但作为一个起点很靠谱,能避免"字小到看不清"或者"字大到一行放不下"这两种极端。
中文字体体积问题得单独说。完整的思源黑体转出来轻松超过 10MB,加载会明显变慢。如果菜单里只有十几个中文词,可以用字体子集化工具先裁一遍,只保留实际用到的字,体积能压到几百 KB。裁剪的时候记得把可能用到的字都带上,比如"启动""安装""工具""系统""返回"这些常用词,不然以后加个新菜单项发现字变成方块,还得回头重做。
5.3 图标批量生成与命名规则
图标我一般做成 32×32 的 PNG,带透明通道。源素材从哪来都行,关键是尺寸和命名。
# 批量把源图缩放成 32x32 并保持透明 mkdir -p icons-out for f in icons-src/*.png; do base=$(basename "$f") convert "$f" -resize 32x32 \ -background none -gravity center -extent 32x32 \ "icons-out/$base" done-extent那一步是为了把非正方形的图补成正方形,不然缩放之后宽高比不一致,显示出来会被压扁。-gravity center保证补边的时候内容居中,视觉上更整齐。
命名必须和 class 名严格一致,全小写,不要有空格。我吃过一次亏:文件名叫Tool.png,配置里写tool,在某个系统上就是不显示,改成全小写之后立刻正常。这种问题排查起来极其浪费时间,因为你会一直怀疑是配置写错了。
图标数量不用太多,五六个足够覆盖绝大多数场景。真要细分到每个发行版一个图标,二十个文件下去,菜单看着确实专业,但维护成本也上去了——每加一个新镜像就得找图、缩放、改名。
5.4 写入、验证与迭代的完整流程
整个流程走一遍大概是这样的:
- 把 U 盘插上,确认数据分区能正常读写。
- 在数据分区根目录建
ventoy/theme/dark-blue/目录。 - 放入
theme.txt、background.png、icons/、fonts/。 - 编辑或新建
ventoy/ventoy.json,写入 theme 插件和需要的其他插件。 - 用 JSON 校验工具检查一遍格式,确认没有语法错误。
- 安全弹出,重启目标机器,进启动菜单看效果。
- 有问题就记下现象,回到第 3 步改,反复迭代。
第 5 步千万别跳过。JSON 的容错性很差,多一个逗号、少一个引号、用了中文标点,整个文件就解析失败,而失败的表现是"所有插件都不生效",看起来像是主题坏了,实际上是配置根本没读进去。我习惯用命令行工具校验:
python3 -m json.tool ventoy.json > /dev/null && echo "JSON OK"还有一个坑前面提过但值得再说一遍:用 Windows 记事本保存 JSON 可能带上 BOM 头,某些解析器会因此报错。稳妥做法是用支持"UTF-8 无 BOM"的编辑器,比如各种代码编辑器,保存时明确选这个编码。
调试阶段建议先把display_mode设成GUI但不指定file,看看 Ventoy 自带的图形菜单能不能正常出来。能出来说明图形终端没问题,再指定自定义主题。这样能把"图形模式不可用"和"主题文件有问题"这两种情况分开,排查效率高很多。
6. 常见问题与排查速查表
6.1 主题完全不生效的五种原因
这个问题的出现频率高到值得单独列一张表。
| 现象 | 最可能的原因 | 处理方式 |
|---|---|---|
| 菜单还是黑底白字 | display_mode没设成GUI | 改成GUI |
| 菜单是图形界面但不是自己的主题 | file路径写错 | 逐级核对路径,确认文件存在 |
| 所有插件都不生效 | JSON 语法错误或编码带 BOM | 用校验工具检查,另存为无 BOM |
| 主题目录放错分区 | 放到了引导分区 | 移到数据分区根目录下 |
| 改了没反应 | 改的是缓存副本或没安全弹出 | 重新插拔,确认写入完成 |
排查顺序建议从外往里:先确认 JSON 能不能被解析,再确认路径对不对,再确认显示模式,最后才怀疑素材本身。从最外层开始排除,永远比一头扎进细节要快。
还有一种隐蔽情况:配置文件里同时存在多个插件块,写法上少了一层嵌套或者多了一个逗号,导致 JSON 整体非法。这种时候表现就是"什么都没生效",包括你之前明明调好的别名也不见了。看到这种"全线崩"的症状,第一反应就该是语法问题,而不是逐个功能去查。
6.2 花屏、错位与黑屏的处理
花屏最典型的成因是分辨率不匹配。你设了 1920×1080,机器只支持到 1366×768,grub2 回退到低分辨率,背景图被拉伸,菜单位置按百分比重算,结果就是背景糊成一片、文字压在图案上。
处理办法有两个方向。一是降低分辨率设定,迁就低端机器;二是干脆不用背景图,改用desktop-color纯色兜底,这样不管什么分辨率都不会花,只是少了点氛围。我现在给"到处插"的盘做的主题,基本都是纯色背景加精细的文字排版,看着干净,兼容性拉满。
错位但没花屏,通常是百分比和像素混用导致的。比如菜单区用百分比定位,但item_height用了很大的像素值,在低分辨率下条目总高度超出容器,就会溢出到容器外面。这种问题的特征是"高分辨率正常、低分辨率溢出",看到这个规律就往尺寸计算上想。
黑屏最吓人,但原因往往很简单:背景图路径错了,同时desktop-color也没设或者设成了纯黑。grub2 找不到图就画个黑底,如果字体颜色又是暗色,那就什么都看不见了。任何时候都设一个和文字颜色对比明显的兜底底色,这一行配置能救很多次命。
6.3 中文显示异常与字体加载失败
中文显示成方块、问号、或者干脆空白,基本可以锁定是字体问题。三个检查点:
第一,字体文件里到底有没有中文字形。用英文字体转出来的 pf2 里只有拉丁字母,中文自然是方块。判断方法很简单,看字体源文件支不支持中文,或者看转出来的 pf2 体积——几 MB 以上的大概率带中文,几百 KB 的基本没有。
第二,theme.txt里引用的字体名和grub-mkfont -n指定的名字是否完全一致。这里连大小写都要对上,ThemeFont和themefont是两个名字。
第三,字体文件放的位置对不对。稳妥做法是放在主题目录下的fonts/子目录里,同时在主题目录根下也放一份。不同版本的加载逻辑略有差异,两处都放能覆盖绝大多数情况。这是我从反复试验里总结出来的土办法,不算优雅但确实有效。
提示:如果只是想先跑通流程,可以暂时全部用英文或者数字做菜单别名,等主题稳定了再上中文。分阶段验证比一次性全上要省心。
6.4 UEFI 与传统引导下的表现差异
同一个主题,在 UEFI 模式下和在传统引导模式下,观感可能不一样,这不是你的错觉。
UEFI 模式下图形输出走的是固件的图形协议,支持的分辨率通常更丰富,1920×1080 基本都能跑,色彩也更准。传统引导模式下,图形能力受限于固件的老式接口,高分辨率不一定支持,而且部分老机器上会出现颜色偏差,深蓝可能显示成偏紫。
我的应对策略是主题设计上避开对颜色精度要求高的元素。比如不用渐变色做文字,不用极细的线条做分隔,这些在色偏的情况下会很难看。纯色块、粗边框、大字号,这些元素在两种模式下都能保持稳定。
另外,传统引导模式下菜单的响应速度会稍慢一点,尤其是图标多的时候。如果发现按键有明显延迟,优先砍图标数量和背景图体积,这两个是最占资源的。
7. 进阶玩法与长期维护
7.1 多套主题的切换与版本管理
做久了自然会攒下好几套主题。切换方式很土但有效:在theme/下放多个目录,改ventoy.json里的file指向不同目录,重启生效。没有热键切换,也没有运行时选择,这是 grub2 的机制决定的。
为了管理方便,我会给每套主题目录配上同名的说明文件,记清楚这套是给什么分辨率用的、字体是什么、图标有哪些。听起来很啰嗦,但半年后你再翻出来,没有说明文件基本等于重做。我现在的目录结构是这样的:
ventoy/theme/ ├── dark-blue-1080/ 1920x1080 深色版 ├── light-gray-768/ 1024x768 浅色兼容版 └── minimal/ 纯色极简版,万能兜底minimal那套是我的保命方案,纯色背景、系统默认字体、不用任何贴图,插到任何机器上都不会出问题。出门带盘的时候默认用它,需要展示的时候再切到精致的那套。
7.2 菜单可读性的长期优化思路
主题做到后面,你会发现真正决定好不好用的不是画面多漂亮,而是菜单信息组织得清不清楚。
我的做法是按用途分组,用别名前缀区分。比如所有系统安装镜像别名都以"安装"开头,所有维护工具以"工具"开头,菜单里自然就形成了视觉分组,找东西快很多。这个技巧不需要任何额外配置,纯靠命名,但效果比配一堆图标还明显。
再进一步是控制菜单项数量。一个盘里塞五十个镜像,界面做得再好看也没人愿意翻。我一般控制在十五个以内,常用的放前面,冷门的挪到子目录里靠树形视图访问,或者干脆换个盘放。菜单是给人用的,不是用来炫收藏的,这个认知我花了不少时间才建立起来。
还有一个细节:别在菜单里放需要解释的条目。如果某个镜像的名字必须加注释才能看懂,那说明命名有问题,改名字比加注释有效。别名写成"某某系统 2024 版 装机用"这种,看一眼就知道干什么,比任何图标都管用。
7.3 我踩过的几个印象深刻的坑
说几个具体的,都是真金白银换来的。
第一个,在错误的编码下编辑配置文件。有一次在某个编辑器里改完保存,主题死活不生效,查了半小时路径和语法,最后发现文件开头多了三个不可见字节。从那以后我养成了一个习惯,改完配置先跑一遍校验命令,通过再往下走。
第二个,背景图用了带透明通道的 PNG。透明部分在 grub2 里会显示成黑色,不是你想的"透出底色"。做背景图的时候一定要先铺一层不透明底色再导出。
第三个,图标尺寸和主题里声明的不一致。我一开始拿 128×128 的图标配上 32×32 的声明,想着让它自己缩,结果边缘糊得厉害,还有锯齿。后来老老实实按目标尺寸出图,问题消失。grub2 的缩放算法很朴素,别指望它。
第四个,忘了倒计时会把默认项启动掉。有次设了 5 秒倒计时做测试,结果每次重启刚看到菜单就自动进了第一项,来来回回折腾了七八次才反应过来是自己设的。测试阶段建议把倒计时关掉,等一切稳定了再加回来。
第五个,在树形视图下用平铺的别名。树形视图的层级是按目录来的,你给每个镜像起了别名,但如果它们散在不同目录里,菜单结构会变得很怪。要么统一放一个目录用列表视图,要么按目录规划好别名,两者别混着来。
7.4 关于这套东西的后续演进
grub2 的主题机制这些年基本稳定,短期内不会有大的变化,所以你做的主题可以用很久。需要注意的是版本差异带来的小行为不同,比如某些版本对字体加载路径的处理、对九宫格贴图缺失时的容错程度,这些细微差别可能让你的主题在新版本上表现略有不同。
我的建议是做好的主题留一份"已验版"快照,把当时的配置文件、素材、字体全部打包存档。以后升级工具或者换 U 盘,直接拿快照恢复,比重新调一遍要快得多。这个习惯来自一次惨痛经历:折腾了一晚上的主题,第二天手滑把目录删了,素材散落在下载文件夹里,找回来花了更长时间。
最后分享一个我觉得挺实用的小技巧。如果你不想每次都重启机器看效果,可以先在电脑上装个 grub2 主题预览工具,把主题文件丢进去,它会模拟渲染出效果图。这类工具不能百分百还原真机效果,尤其是分辨率和字体渲染的细节,但用来验证布局、检查元素有没有超出边界、确认图标有没有正确匹配,效率比反复重启高太多了。先用工具把明显问题排掉,真机只用来做最终确认,整个流程能缩短一大半。