图片转 Base64 有什么用?Data URI 用法与体积代价

图片转 Base64 的用处,是让图片能塞进只收文本的地方:HTML、CSS、JSON、配置文件。Base64 是一种把二进制字节改写成 64 个可打印字符的编码方式,前面再加上 data:image/png;base64, 这样的前缀,就成了浏览器能直接当图片地址用的 Data URI。代价是体积固定变成原来的 4/3。下面讲清怎么写、亏在哪、什么图该内嵌。

Base64 是什么?体积为什么会变大?

Base64 把每 3 个字节拆成 4 组 6 位,再用 64 个字符逐组表示,所以输出长度固定是输入的 4/3。这 64 个字符是 A~Z、a~z、0~9 加上 + 和 /,全都是可打印字符,放进任何文本里都不会被当成控制符。

长度可以直接算:

Base64 字符数 = 4 × ⌈原始字节数 ÷ 3⌉

字节数不是 3 的倍数时,末尾用一个或两个 = 补齐。用几张图实测,比例几乎钉死在 1.3333:

样图原始大小Base64 长度比例
人像照片 JPG68,052 字节90,736 字符1.3333
静物照片 JPG72,326 字节96,436 字符1.3334
人像照片 PNG424,520 字节566,028 字符1.3333
32px 小图标 PNG3,769 字节5,050 字符(含前缀)1.34

小图标的比例略高,是因为 data:image/png;base64, 这 22 个字符的前缀在小文件里占比更明显。这里有个常见误解:Base64不是压缩,也不是加密,它只是换了一种写法,任何人都能原样解回图片。

Data URI 在 HTML、CSS、JSON 里怎么写?

格式固定为 data:[类型];base64,[内容],类型要和图片真实格式一致,PNG 写 image/png,JPG 写 image/jpeg。下面是四种常见写法。

HTML 图片标签

<img src="data:image/png;base64,iVBORw0KGgo..." alt="搜索" width="16" height="16">

和普通图片一样补上 alt 和宽高,否则读屏软件读不出含义,页面也会在加载时跳动。

CSS 背景图

.icon-search {
  background-image: url("data:image/png;base64,iVBORw0KGgo...");
}

JSON 接口或配置文件

{
  "avatar": "iVBORw0KGgo...",
  "avatarType": "image/png"
}

接口里通常只放纯 Base64,类型单独用一个字段说明,前端拼成 Data URI 再显示。

SVG 图标:不用转 Base64

SVG 本身就是文本,直接做 URL 编码写进去更短,而且源码可读、可改颜色:

background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' ...%3E");

实测一个 213 字节的放大镜图标,Base64 版 Data URI 是 310 个字符,URL 编码版是 250 个字符,短了约 19%。写法要点是把双引号换成单引号,并转义 < > # % 这几个字符。

PNG、JPG、WebP 这些二进制图片没法这么写,只能走 Base64。用图片转 Base64可以一键生成上面四种形式,不用手动拼前缀。

开了 gzip,还要在乎那 33% 吗?

传输层面基本不用在乎,真正的代价在别处。Base64 只用了每个字符 8 位里的 6 位,gzip 恰好能把这部分冗余压回去。

样图原图Base64 文本Base64 经 gzip相对原图
人像 JPG68,05290,73668,107+0.1%
静物 JPG72,32696,43672,504+0.2%
人像 PNG424,520566,028426,111+0.4%

单位为字节。换成 Brotli 压缩,结果与原图基本持平。所以“内嵌会让下载量多三分之一”这个说法,在开了压缩的服务器上并不成立。内嵌大图真正亏在下面几件事:

  • 没法单独缓存。图片写进 CSS 后,改一个颜色、调一个间距,整份 CSS 连同里面的图片都要重新下载。单独的图片文件则能长期缓存。
  • 拖慢首屏。CSS 是阻塞渲染的资源,浏览器要等它下载并解析完才开始绘制页面。往 CSS 里塞一张 100KB 的图,等于让整个页面多等这 100KB。
  • 不能懒加载。普通图片可以等滚动到视口附近再加载,内嵌的图片随 HTML 或 CSS 一起到达,看不看得到都要付出成本。
  • 重复引用会重复计费。同一个 Data URI 在页面里写三次,就是三份数据;普通图片链接只下载一次。
  • 解压后仍是 4/3。gzip 只省传输,浏览器内存里的文本还是完整大小,还要多一步解码。

什么图该内嵌,什么图不该?

一句话:小、少、稳的图内嵌,大、多、常变的图走链接。前端构建工具 Vite 默认把 4KB 以下的资源自动转成 Base64 内联,这个值可以作为日常判断的参考线。

场景建议理由
几 KB 的按钮图标、加载动画内嵌省一次请求,首屏立即可见
单文件 HTML 报告、离线演示页内嵌发一个文件就能完整打开
JSON 接口里的小头像、签名图可以内嵌接口只能传文本时的常规做法
照片、横幅、商品图不内嵌体积大,拖慢首屏,失去缓存
多个页面共用的 Logo不内嵌单独文件缓存一次,所有页面复用
HTML 邮件里的图片谨慎各邮件客户端支持不一,部分会直接不显示

HTML 邮件里为什么要谨慎

邮件不是浏览器,各家客户端对 Data URI 图片的处理差别很大:有的正常显示,有的出于安全考虑直接屏蔽,显示成一个空白框。发营销邮件或通知邮件时,稳妥的做法有两种:一是把图片放在服务器上用普通链接引用;二是把图片作为附件嵌入,正文里用cid: 引用它。不管选哪种,群发前都要在常用的几个客户端里各发一封测试邮件看效果。

内嵌前先把图压小

Base64 会原样放大原图的体积,所以先压缩再编码,收益会被 4/3 一起放大。一张 12KB 的图标压到 4KB 再转,内嵌后是约 5.4KB 而不是 16KB。小图标先用压缩图片处理一遍,带透明的保持 PNG 或 WebP 格式。

解码 Base64 时要注意什么?

以文件头判断格式,不要相信前缀里写的类型。data:image/png;base64, 只是一段谁都能写的文本,内容可能根本不是 PNG,甚至不是图片。可靠的判断方式是看解出来的前几个字节:PNG 以固定的 8 字节签名开头,JPG 以 FF D8 开头。小鹿 Image 的解码就是按文件头判断,前缀和内容对不上时以内容为准,不是图片则直接报错。

常见的解码失败原因

  • 复制不完整:日志、聊天记录常把长文本截断,解出的图片下半截发灰或损坏。
  • 混入了别的字符:换行、空格一般会被忽略,但中文引号、省略号混进去就会解错。
  • URL 安全变体:有的系统把 + 和 / 换成了 - 和 _,需要解码器兼容这种写法。
  • 内容被转义过:JSON 里的斜杠有时被写成 \/,先还原再解码。

安全上的两个边界

一是主流浏览器会拦截网页用链接或脚本跳转到 data: 地址,这是为了防止伪装成正常网址的钓鱼页;在 img 标签和 CSS 里当图片用则不受影响。二是来路不明的 SVG 类 Data URI 不要当网页直接打开,SVG 里可以带脚本,作为 img 显示时脚本不会执行,单独打开则不一定。

需要把 Base64 还原成文件时,直接粘进图片转 Base64的解码一侧;想了解各图片格式本身的差别,可以看图片格式怎么选

常见问题

图片转 Base64 有什么用?
让图片能放进只接受文本的地方。常见用法有:把小图标写进 CSS 或 HTML 省一次网络请求;把图片作为字符串放进 JSON 接口、配置文件或数据库文本字段;在单文件 HTML 报告、离线页面里自带图片,不依赖外部文件。
Base64 之后体积会变大多少?
固定变成原来的约 4/3,也就是大 33%。原因是 Base64 用 4 个字符表示 3 个字节。实测一张 68,052 字节的 JPG,编码后是 90,736 个字符,比例 1.3333;再加上 data:image/jpeg;base64, 这 23 个字符的前缀。
服务器开了 gzip,Base64 还会更大吗?
传输层面几乎不会。实测三张 JPG 和两张 PNG 的 Base64 文本,gzip 压缩后只比原图大 0.1%~0.4%,Brotli 基本持平。但文件在浏览器里解压后仍是 4/3 大小,并且失去单独缓存、懒加载的能力,这些才是内嵌大图的主要代价。
多大的图片适合转 Base64 内嵌?
几 KB 以内、页面必用、很少变动的小图标适合。前端构建工具 Vite 默认把 4KB 以下的资源自动内联,可以作为参考线。照片、横幅图、会在多个页面复用的图片,用普通图片链接更好。
Data URI 和纯 Base64 有什么区别?
Data URI 是“data:类型;base64,”前缀加上 Base64 内容,浏览器能直接把它当图片地址用,写在 img 的 src 或 CSS 的 url() 里。纯 Base64 只有编码后的内容,通常用于 JSON 字段或接口传参,由接收方自己知道它是什么格式。
Base64 怎么转回图片?
把内容粘贴到图片转 Base64 工具的“Base64 → 图片”一侧即可,带 data: 前缀、带引号、带 url() 包裹或中间有换行都能识别。工具按文件头判断真实格式,前缀写错了类型也能还原成正确的文件。
解码出来的图片只显示一半或打不开是怎么回事?
多半是复制不完整。Base64 文本很长,从日志、聊天记录或截断的接口返回里复制时容易少掉末尾一段,解出来的图片下半部分会变成灰色或直接损坏。回到源头完整复制一次;如果末尾缺了 = 补位符,一般不影响解码。
图片转 Base64 会上传图片吗?
不会。小鹿 Image 的编码和解码都在浏览器本地完成,图片和生成的文本都不会发送到服务器。

动手试试

看完直接动手——用图片转 Base64工具,在浏览器本地处理,图片不上传、免费无需注册。

参考资料

「小鹿 Image」团队维护,更新于 2026-09-20。如发现问题或建议,欢迎通过反馈入口联系我们。