图片 Base64 互转详解:Data URI 的取舍
Data URI 是什么
平常网页引用图片是”外部链接”:HTML 里写 <img src="logo.png">,浏览器再发一个请求去拉 logo.png。Data URI 是另一种方式——把图片的二进制数据直接编码进 URL 字符串里,浏览器不用额外请求就能渲染:
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUg..." />
data: 是协议头,image/png 是 MIME 类型,base64 是编码方式,后面跟图片二进制的 Base64 编码。整串就是图片本身,自包含、无外部依赖。
图片转 Base64 就是把图片文件的字节用 Base64 编码成这串文本;反过来 Base64 解码就还原成图片文件。
Base64 编码的代价:体积膨胀
Base64 不是压缩,是编码——它用 64 个可打印字符(A-Za-z0-9+/)表示任意二进制。原理是把每 3 字节(24 位)拆成 4 组 6 位,每组映射成一个字符。
代价是体积变大约 1/3:3 字节变 4 字节,膨胀率 4/3 ≈ 133%。一张 30KB 的 PNG 转 Base64 后约 40KB。
所以”Base64 能减小体积”是误解——它从不压缩,反而变大。它的价值不在省体积,在省请求。
什么时候该用 Base64 内嵌
Base64 内嵌的核心收益是减少 HTTP 请求数。早期 HTTP/1.1 时代,浏览器对单域名并发请求有限制(6 个左右),大量小图标各自请求会排队阻塞。把小图内嵌进 HTML/CSS,省掉这些请求,加载更快。具体适用:
- 极小图标(< 4KB):图标本身的请求开销(HTTP 头、握手)可能比图标数据还大,内嵌反而省
- CSS 背景图、sprite 替代:小装饰图内嵌进 CSS,减少请求数
- 单文件交付:HTML 邮件、单页 demo、离线文档——必须自包含不能有外部依赖时
- API 传输图片:某些 JSON API 用 Base64 字段传图,避免多部分表单的复杂度
什么时候不该用
Base64 不是银弹,滥用反而更慢:
- 大图:照片转 Base64 会让 HTML/CSS 文件膨胀很多,阻塞主文档解析。大图老老实实当外部资源,让浏览器并行加载
- HTTP/2+ 环境:HTTP/2 支持多路复用,并发请求开销大幅降低,内嵌省请求的收益变小。现代站点用 HTTP/2,Base64 的优势减弱
- 可缓存的图:外部图片能被浏览器和 CDN 缓存,多个页面复用。内嵌进 HTML 的 Base64 每次都随 HTML 重新下载,无法跨页缓存——这是大缺陷
- 需要懒加载的图:Base64 内嵌在 HTML 里会立即随文档加载,没法懒加载
经验阈值:小于 4KB 且不跨页复用的小图适合内嵌;大于 4KB 或多页复用的图用外部文件。
Data URI 的细节
几个实践要点:
MIME 类型
data:image/png;base64,... 里的 MIME 必须正确。常见:
- PNG →
image/png - JPEG →
image/jpeg - WebP →
image/webp - SVG →
image/svg+xml(SVG 本就是文本,可以不用 base64,直接data:image/svg+xml,<svg...>)
MIME 写错可能导致浏览器无法识别。
CSS 中使用
.icon {
background-image: url("data:image/png;base64,iVBOR...");
}
CSS 里 Data URI 要注意引号和特殊字符,Base64 含 +/= 在某些上下文需 URL 安全编码(+→-、/→_、去掉 =),即 Base64URL 变体。
SVG 的特殊性
SVG 是文本格式,转 Base64 反而多此一举——SVG 可以直接内嵌(data:image/svg+xml,<svg ...> 甚至直接 <svg> 标签)。SVG 内嵌进 HTML 还能用 CSS 控制颜色,比 Base64 灵活得多。
安全和隐私
- Base64 不是加密,任何人解码就能还原原图。别用它”保护”图片
- 图片的 EXIF 元数据(含 GPS、拍摄时间、设备)会原样保留在 Base64 里。分享截图/照片转 Base64 前若在意隐私,先用工具去 EXIF
- Data URI 里可能藏恶意内容,邮件/富文本场景渲染别人提交的 Data URI 要净化
反向:Base64 还原图片
解码场景:API 返回的 Base64 图片字段、爬取到的 Data URI、邮件内嵌图。解码流程就是 Base64 解码成字节流,按 MIME 类型保存成对应格式文件。注意去掉 data:...;base64, 前缀只取数据部分,否则解不出来。
小结
图片 Base64 互转是”二进制 ↔ 文本”的编码转换,代价是体积膨胀 1/3,收益是省 HTTP 请求。它适合小图内嵌(<4KB、单页、不可缓存场景),不适合大图和需跨页缓存的图——HTTP/2 时代其优势进一步缩水。记住 Base64 不压缩、不加密、保留元数据这三个特性,就能正确判断何时用它。Base64 编码本身的原理详见 [[base64]]。