二、位图 vs 矢量图
要理解 SVG 和 PNG 的区别,先要理解一个更基础的概念:位图和矢量图。
位图(Raster Image)
位图是用像素点阵表示图像的方式。一张 100x100 的位图,就是 10000 个像素点,每个点记录自己的颜色。
放大位图时,你会看到一个个方块——因为像素被拉伸了,细节会模糊。
常见的位图格式:JPG、PNG、GIF、BMP、WebP。
矢量图(Vector Image)
矢量图是用数学公式描述图像的方式。一个圆不是由一堆像素组成,而是由"圆心位置 + 半径 + 颜色"这样的描述组成。
放大矢量图时,浏览器实时重新计算并绘制,所以无论放大多少倍都不会模糊。
常见的矢量格式:SVG、AI、EPS、PDF(部分)。
对比表
| 维度 | 位图 | 矢量图 |
| 表示方式 | 像素点阵 | 数学公式 |
| 放大效果 | 模糊、有锯齿 | 始终清晰 |
| 适合内容 | 照片、复杂渐变 | Logo、图标、插画 |
| 文件体积 | 取决于分辨率 | 取决于复杂度 |
| 编辑性 | 难(改像素) | 强(改代码) |
二、SVG 是什么
SVG(Scalable Vector Graphics,可缩放矢量图形)是基于 XML 的矢量图格式,由 W3C 在 2001 年标准化。
一个简单的 SVG 例子:
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
<circle cx="50" cy="50" r="40" fill="red" />
<rect x="20" y="20" width="60" height="60" fill="blue" />
</svg>
这段代码画了一个红圆和一个蓝方块。它的特点:
- 本质是文本:用 XML 标签描述图形,可以用记事本打开编辑
- 无限缩放:放大到任何尺寸都清晰
- 可被 CSS/JS 控制:能改变颜色、做动画、响应交互
- 文件体积小:简单图形的 SVG 通常比 PNG 小很多
- 支持动画:原生支持
标签和 CSS 动画
三、PNG 是什么
PNG(Portable Network Graphics,便携式网络图形)是一种无损压缩的位图格式,1996 年发布,目标是替代有专利争议的 GIF。
PNG 的特点:
- 无损压缩:压缩后画质不损失,适合需要精确还原的场景
- 支持透明:8 位 alpha 通道,支持半透明(GIF 只支持 1 位透明)
- 不支持动画:APNG 是后加的扩展,兼容性一般
- 体积较大:照片类内容 PNG 比 JPG 大很多
- 像素精确:每个像素的颜色值都被完整保留
PNG 有几种变体:
| 类型 | 说明 |
| PNG-8 | 256 色,类似 GIF,体积最小 |
| PNG-24 | 真彩色,无透明 |
| PNG-32 | 真彩色 + 透明通道,最常用 |
四、SVG vs PNG 对比
| 维度 | SVG | PNG |
| 类型 | 矢量图 | 位图 |
| 放大效果 | 始终清晰 | 模糊 |
| 透明度 | 完全支持 | 支持(8 位 alpha) |
| 动画 | 原生支持 | 不支持(APNG 例外) |
| 可编辑 | 文本编辑 | 像素编辑 |
| 可被 JS 操作 | 是 | 否 |
| 体积(简单图) | 很小(几 KB) | 中等(几十 KB) |
| 体积(复杂图) | 可能很大 | 固定 |
| 浏览器支持 | 现代 + IE9+ | 所有 |
| 适合内容 | Logo、图标、图表、插画 | 照片、截图、复杂渐变 |
体积对比示例
| 图片内容 | SVG 大小 | PNG 大小 | 胜出 |
| 简单 Logo | 1 KB | 8 KB | SVG |
| 图标(单色) | 0.5 KB | 3 KB | SVG |
| 卡通插画 | 15 KB | 60 KB | SVG |
| 风景照片 | 500 KB+ | 200 KB | PNG |
| 文字截图 | 800 KB+ | 150 KB | PNG |
可以看到一个规律:图形越简单、色块越少,SVG 越有优势;图像越复杂、色彩越丰富,PNG 越有优势。
五、什么时候用 SVG
1. Logo 和品牌图标
公司 Logo 通常需要在各种尺寸下使用——网站顶栏(24px)、邮件签名(100px)、广告牌(1000px+)。SVG 一份文件搞定所有尺寸,永远不会模糊。
<img src="logo.svg" alt="Logo" width="32">
<img src="logo.svg" alt="Logo" width="512">
<!-- 两个用同一个文件,都清晰 -->
2. UI 图标
现代设计系统里的图标几乎都是 SVG。原因:
- 一套图标适配所有分辨率(普通屏、Retina、4K)
- 可以用 CSS 改颜色(不用为每种颜色准备一份)
- 可以用 JS 做交互(hover 变色、点击动画)
<svg class="icon" viewBox="0 0 24 24">
<path d="M12 2L2 22h20L12 2z" fill="currentColor"/>
</svg>
.icon { color: gray; }
.icon:hover { color: red; }
3. 数据可视化图表
折线图、柱状图、饼图——这些用 SVG 渲染最合适,因为:
- 数据变化时可以平滑动画
- 鼠标可以 hover 到每个数据点
- 可以导出为矢量 PDF
主流图表库 D3.js、Chart.js、ECharts 都支持 SVG 渲染。
4. 简单插画
扁平化风格插画、吉祥物等色块简单的图,SVG 体积小且清晰。
六、什么时候用 PNG
1. 照片
照片的像素信息太复杂,用 SVG 描述会非常冗长,体积甚至比 PNG 还大。这种场景 PNG(或 JPG/WebP)是正确选择。
2. 复杂渐变和阴影
多层渐变、模糊效果、噪点纹理——这些效果在 SVG 里要么做不到,要么体积爆炸。PNG 更合适。
3. 截图
软件截图、网页截图本质上是位图,里面的文字和像素细节用 PNG 保留最准确。
4. 需要像素精确的图像
医学图像、设计稿等需要 1:1 还原的场景,PNG 的无损特性是关键。
七、SVG 的实用技巧
1. 内联 SVG 更灵活
直接把 SVG 代码写在 HTML 里,比 引用更灵活——可以用 CSS 控制内部元素:
<!-- 比 <img src="icon.svg"> 更灵活 -->
<svg viewBox="0 0 24 24" class="icon">
<path class="icon-path" d="..." />
</svg>
<style>
.icon-path { fill: currentColor; transition: fill 0.3s; }
.icon:hover .icon-path { fill: red; }
</style>
2. 用 currentColor 实现主题色
fill="currentColor" 让 SVG 继承父元素的 color,主题切换时只需要改 CSS:
<div style="color: blue">
<svg><path fill="currentColor" d="..."/></svg>
</div>
3. 压缩 SVG
SVG 本质是文本,可以用 SVGO 等工具压缩——移除注释、空格、冗余属性,体积能减小 30%-50%。
八、SVG 的安全注意
SVG 是 XML,可以内嵌 和外部资源。这意味着:
- 不要把用户上传的 SVG 直接展示给其他用户(XSS 风险)
- 用
加载 SVG 是安全的(脚本不会执行) - 内联 SVG 或用
加载会执行脚本,需要净化处理
生产环境如果要展示用户上传的 SVG,必须先用 DOMPurify 等工具过滤。
九、两者结合:图标系统的最佳实践
现代前端图标系统的典型做法:
- 设计阶段:设计师用 Figma/Sketch 画矢量图标
- 导出 SVG:每个图标导出一份 SVG
- 打包处理:用工具(svgr、vue-svg-loader)把 SVG 转成组件
- 使用:
,内部渲染为内联 SVG
// React 示例
import HomeIcon from "./icons/home.svg";
function Header() {
return <HomeIcon className="icon" />;
}
这样既有 SVG 的清晰度和灵活性,又有组件的复用性。
十、实践推荐
日常开发中经常需要把 SVG 和 PNG 互转——设计师给的是 SVG 但要用在位图场景,或者反过来把 PNG 图标矢量化。在线工具最方便:
- SVG 转 PNG 工具:https://52tool.net/tools/image/svgToPng
支持 SVG 转 PNG、自定义输出尺寸和背景色,也可以反过来 PNG 转 SVG(适用于简单图形矢量化)。处理 Logo、图标时特别实用。