给一个开源小工具做图标那次,我在这枚图形上花了整整两天:24×24 网格上一个圆角方框加一道弧线。源文件是 SVG,我相当满意,然后开始交付——小程序后台说不收 SVG,应用图标要 1024×1024 的位图,网页的 manifest 要 192 和 512 两份,文档里的徽标又是另一套尺寸。最糟的是第一次转出来的 32px 图标,那道 1px 的弧线直接消失了,看上去像个方框缺了一角。栅格化这件事,真不是"改个后缀"。
一、从矢量到位图,中间发生了什么
SVG 存的是路径、描边宽度和颜色,浏览器拿到之后按当前显示尺寸重新计算一遍;位图存的是每个像素的颜色值。转换的正式名字叫栅格化:把你指定的宽高切成格子,逐格算出该填什么色。所以输出清不清楚,取决于你填进去的那两个数字,跟 SVG 内部 viewBox 是 24 还是 2400 没有直接关系。
| SVG(矢量) | PNG / JPG / WebP(位图) | |
|---|---|---|
| 放大表现 | 路径重算,边缘始终干净 | 像素被插值,会发糊或出现锯齿 |
| 体积 | 图标这类简单图形通常几 KB | 随像素数量增长 |
| 谁能接收 | 浏览器、设计软件 | 平台后台上传位、系统图标、几乎所有场景 |
| 透明 | 支持 | PNG 支持;JPG 没有透明通道,会被填成白底 |
| 可否改图形 | 改代码就能改 | 只能重画 |
二、我这份图标最后交了哪些尺寸
- 1024×1024 PNG:母版,不带圆角,四周留白按图形宽度的 10% 留。
- 512×512 和 192×192 PNG:网页 manifest 里那两档。
- 64×64 和 32×32 PNG:站点标签、文档内嵌小图。
- 1200×630 WebP:社交分享卡片底图,质量我拉到 90%。
这张清单是我和后台提示一项一项对出来的。规则会变,每次交付前我都再核一遍,不指望记住。
至于那道 32px 上消失的弧线,我后来的解法是先往大导出、再缩小:出 128×128,然后在自己的图像软件里缩到 32。原因是 SVG 里 1px 的描边落到 32px 的输出网格上,连一个像素都占不满,栅格化只能把它抹平。
三、我实际转一份的流程
- 先在SVG图片预览里确认渲染结果。有些 SVG 用了外部字体、CSS 变量或者
foreignObject,源码看着没问题,浏览器里根本不显示,这一步能提前发现。 - 把文件放进SVG 转换格式,选输出格式,填目标宽高。勾上等比时只填一个数,另一边让它按比例算,避免把圆压成椭圆。
- 图标一律 PNG,因为要透明底;照片类素材用 JPG;网页里想省体积选 WebP,质量滑条 10%–100% 那档只对 JPG 和 WebP 有意义。
- 下到本地用系统看图放大到 400% 看边缘,再实际放进使用位截一张(比如浏览器标签、聊天窗口的分享卡),确认在真实尺寸下还认得出这是那枚图标。
四、反复出现的几个坑
- 尺寸填小了:viewBox 是 24,输出框里也顺手填 24,拿到的就是一张 24px 的图,再放大到 1024 就是一团马赛克。输出尺寸要按使用位真正需要的像素填,不是按源文件的逻辑尺寸填。
- 想要 JPG 的透明底:JPG 本身没有 alpha 通道,透明区域会被填成白色,这不是转换时勾一下选项能解决的。
- 颜色对不上设计稿:SVG 里的渐变和滤镜依赖浏览器渲染,某些色值转出来和设计软件里不完全一致。我的原则是以转出的位图为准回改 SVG,而不是反复重转。
- 只给了位图想要矢量:那是反方向的活,得走描摹,出来的路径是近似结果,别期待跟原稿一模一样。
- 一次交很多个规格:我的习惯是一份一份转,每转完一个就核对一次尺寸和透明,因为不同规格的参数本来就不一样。
五、导出尺寸我是怎么定的
我的取数原则只有一句:按那个位置真实显示多大来算,再乘以 2,最后往上取到常见档位。乘以 2 是为了高分屏,往上取档是因为平台后台往往只接受固定几档。这次交付我实际填的数字如下:
| 使用位 | 页面上显示约多大 | 我导出的尺寸 | 格式与透明 |
|---|---|---|---|
| 浏览器标签 | 16×16 | 32×32,另存一份 64×64 备用 | PNG,保留透明 |
| 桌面快捷方式 | 48–72dp | 192×192 | PNG,保留透明 |
| 应用后台图标位 | 约 150–170 | 1024×1024 | PNG,四周留白 10% |
| 聊天窗口分享卡片 | 约 600×315 | 1200×630 | WebP,质量 90% |
| 文档里的品牌字标 | 24–32 高 | 64×64 | PNG,保留透明 |
对照表里最容易被忽略的是"留白"这一栏。图形本身塞满画布时,进了系统自动加的圆角遮罩里就会被切掉边缘,我那枚图标的弧线第一次就是贴边贴太紧,在 192 那一档上被削掉了两个端点。
六、常见疑问
Q:SVG转PNG会失真吗?
输出尺寸够大就不会。失真几乎都来自尺寸定得比使用位还小,或者源图形里存在 1px 级细节,落到小网格上被抹平。
Q:想要透明背景该选哪个格式?
PNG。JPG 不支持透明,会填成白底;WebP 支持透明,同画质下体积更小,但要确认接收方那个后台认不认 WebP。
Q:质量滑条对PNG有用吗?
我实测影响的是 JPG 和 WebP。PNG 是有损还是无损由格式本身决定,所以我出 PNG 的时候只调尺寸,不动质量。
Q:为什么转出来的图有白边?
多半是抗锯齿:路径边缘的半透明像素在深色背景上会显出一圈浅边。我的做法是导出透明 PNG 之后在使用位里看效果,明显的话把图形外轮廓稍微往里收一点。
Q:SVG 会被上传吗?
不会,转换在浏览器本地完成。给未公开项目做图标时,这一条是我能不能用它的判断标准。
那天之后我改了交付习惯:图标源文件除了 SVG,一定同时附一份"尺寸—格式—是否透明"的对照表,把每个使用位写清楚。转换本身只是一次填数字的动作,前面那份表才是真正省时间的东西。