做 UI 最烦的不是画图,是收尾:背包里 48×48 的图标、240×64 的按钮、400×48 的标题条尺寸全不一样,如果一张图一次加载,几十个 UI 元素就是几十次读取。图集(Atlas)就是把它们排进一张大图,配一个记录每块坐标的数据文件,引擎按坐标去取——读取次数从几十次变成一次。难点在「尺寸不一样怎么排才不浪费」:这一页用 MaxRects 算法自动装箱,并把结果全部摊开给你看:填充率多少、实际用了多少像素、排成了几页、有没有图塞不下,都是实测数字。排完直接导出 TexturePacker JSON / Cocos plist / Godot tres / CSV,Unity、Cocos、Godot、Phaser 拿去就能读。全程在浏览器本地处理,图片不上传服务器。
批量拖入 · MaxRects 自动装箱 · 填充率实测 · 扩边防串色 · 2 的幂对齐 · 超过 2048 自动分页 · 五种数据格式 · 导出 ZIP
PNG / JPG / WebP,尺寸各不一样也没关系
三件事:① 读取次数——20 个 UI 元素散着放要读 20 次,合成一张只要 1 次;② 显存——每张图单独上传都会按 2 的幂对齐补齐,散图浪费的显存比你想的多;③ 合批——同一个图集里的元素在多数引擎里能合并成一次绘制(draw call),UI 元素多了这一步的差别很明显。代价是:改一张图要重新打一次包,所以图集一般在素材定稿后再打。
有。用页面里的示例 8 张图(32×32 ~ 400×48)实测,间距 2、扩边 0:
| 设置 | 合图尺寸 | 画布像素 | 填充率 | 页数 |
|---|---|---|---|---|
| 实测中… | — | — | — | — |
一般规律:70% 以上算排得不错,50% 以下通常是尺寸差异太大(比如一张 400 宽和一堆 32 宽混在一起)。这张表是页面自己跑出来的,你拖自己的图进来也会实时重算。
表里有个反直觉的地方值得单独说:勾了 trim,画布明明变小了,填充率反而更低。因为填充率的分子分母同时变小——被裁掉的透明边既不算「占用」也不算「画布」,比例自然回落。所以比较 trim 要看「画布像素」这一列(示例里 140k → 124k,实际省掉 11%),别只盯百分比。同理 2 的幂那档填充率掉得厉害,但那是老设备要求付的固定代价,不是排得差。
合图里两块图是紧挨着的。图片被缩小显示时,GPU 采样会在边缘取到邻居那一格的像素——表现就是按钮边缘冒出一条别的颜色,或者透明区外面渗出一圈色。扩边(extrude)的做法是把每块图的边缘像素向外复制 2 圈,让采样落在自己身上。注意两件事:扩边必须和间距一起用(否则扩出去的像素会盖到邻居上,这一页会自动保证间距不小于扩边);扩边会让 frame 变大 4 个像素,数据文件里已经算进去了,你在引擎里取到的还是原始内容。
因为 trim 会改掉图的原始尺寸,而 UI 里大量元素是靠原始尺寸定位的——最典型的就是九宫格(九切)图:你量好的 12px 圆角边界,trim 之后偏移全变了,九切坐标直接失效。trim 对「纯图标、不需要对齐」的图能省不少空间,但面板、按钮、边框这类要拉伸的图千万别开。开了的话数据文件里会用 spriteSourceSize 记录偏移,引擎能还原位置,但九切边界仍然得你自己重算。
看目标环境:网页、Unity、Godot、小游戏现在都不要求 2 的幂,默认「自动裁到最小」最省。只有很老的 GPU / OpenGL ES 1.x 才强制要求,或者你要开 mipmap 且引擎要求 POT。勾选后画布会向上取到 512 / 1024 / 2048,填充率会明显下降(比如内容只用到 700×300,也会给到 1024×512)——这是必须付的代价,页面会如实把新数字算给你看。
工具会自动分页:装到装不下就开新的一页,导出时每页一张合图 + 一份数据文件(atlas-0、atlas-1…)。这是自动的,你只要看汇总条里的「页数」。如果某一张图本身就超过最大边长(比如 3000×2000 塞进 2048),它会单独列出来告诉你装不下——这时该去把它缩小,或者把最大边长提到 4096。
| 格式 | 给谁用 | 说明 |
|---|---|---|
| JSON(hash) | Unity、Starling、多数加载器 | 以文件名为 key,取值最快,TexturePacker 的默认格式 |
| JSON(array) | Phaser 3、PixiJS | frames 是数组,这两个框架的加载器默认读这种 |
| Cocos plist | Cocos2d-x / Cocos Creator | format 3 标准格式,含 offset / sourceSize,trim 也能对上 |
| Godot .tres | Godot 3 | 每个 sprite 生成一个 AtlasTexture 资源,拖进项目直接用 |
| CSV | 自查 / 自己写解析器 | 一行一个 sprite,坐标尺寸全摊平 |
不管选哪种,合图都是同一张,只是配套的数据文件不同;ZIP 里两个都有。
那边是等宽网格:序列帧动画每一格一样大,按行列排就行,靠行列号定位。这边是异形尺寸:UI 元素高矮胖瘦都不一样,等宽网格会浪费大量空间(按最大的那张对齐),所以必须用装箱算法,并且必须输出坐标数据(没有数据文件,引擎不知道每块在哪)。简记:动画用精灵图,UI 用图集。
免费,无水印、无需注册。装箱和渲染全在你自己的浏览器里跑完,图片不经过任何服务器。