图片转 Base64

把图片转成 Base64 data URI,也可以把 data URI 解码还原为图片。会如实显示体积代价,帮你判断值不值得内联。

所有处理均在你的浏览器内完成,数据不会上传。

使用方法

  1. 拖入一张图片,或点击选择。
  2. 查看体积对比——原始大小、编码后大小,以及增幅百分比。
  3. 选择输出格式:data URI、纯 Base64、CSS、HTML 或 Markdown。
  4. 切换到 Base64 → 图片 可以反向还原并下载。

关于内联图片

data URI 把图片的字节直接放进你的 HTML 或 CSS,而不是指向一个独立文件。好处很直观:少一次 网络请求,也不会出现断链。代价则不那么直观,而且分成两部分。

第一部分是算术。Base64 把 3 个字节编成 4 个字符,因此数据总是比原文件大约多 33%。这没有 办法绕开——正是这种编码方式让它可以安全地嵌进文本。

第二部分才是真正要紧的,而且容易被忽略:内联的图片无法被单独缓存。一个普通图片文件下载 一次之后,只要缓存还在,引用它的每个页面都能复用;而内联的图片是文档的一部分,每次加载页面 都要跟着重新传一遍,每个页面都如此——并且因为它就嵌在 HTML 或 CSS 里,浏览器必须等它完整到达 才能开始渲染。一张 50 KB 的内联背景图,会拖慢每一次页面访问的首屏;而同一个文件如果是独立 请求,只会被取一次,之后再不用取。

还有一段历史值得知道。大量推荐使用 data URI 的建议来自 HTTP/1.1 时代——那时浏览器对每个域名 只允许大约六个并行连接,每次请求都有实实在在的排队成本。在 HTTP/2 与 HTTP/3 下,请求在单条 连接上多路复用,这个代价基本消失了。内联的理由,比你现在仍能看到的那些建议所说的要弱得多。

至今仍然成立的用途是「小而重复」:几百字节、全站都在用的图标,很小的背景纹理,或者需要在 任何其它请求完成之前就出现的图像。两三 KB 以下,省下的那次往返通常划算;到了十 KB 上下, 通常就不划算了。

常见问题

为什么转出来的 Base64 比原文件大?

Base64 用 4 个字符表示 3 个字节,因此编码后必然大约多出 33%——这是算术结果,不是实现效率问题。再加上 data:image/png;base64, 这段前缀,一个小图标的体积增幅可能超过三分之一。本工具会显示确切数字,因为它正是决定「值不值得内联」的那个数,而多数转换工具并不显示。

什么情况下才真的该内联图片?

当它很小、且几乎出现在每个页面上时——图标、很小的 logo、背景纹理。大约 2 KB 以下,省下的那次请求通常抵得过多出来的字节;超过 10 KB 就很少划算。中间那段取决于你的页面,诚实的回答是实测,而不是套一条规则。

为什么大图不该内联?

两个原因叠加。字节多出三分之一;更要紧的是,内联的图片无法被单独缓存。普通图片下载一次后可以在引用它的所有页面上复用;内联的图片是文档的一部分,每次加载页面都要跟着重新传一遍,而且因为它嵌在 HTML 或 CSS 里,浏览器必须等它全部到达才能开始渲染。HTTP/2 之后,「减少请求数」这个理由也弱了很多——并行请求不再像过去那样排队。

图片类型是怎么识别的?

从文件头的头几个字节识别,不看文件名。这一点很关键:把 JPEG 改名成 .png,按文件名工作的转换器就会生成一个声明 image/png 而内容是 JPEG 的 data URI。浏览器通常照样渲染,但邮件客户端、PDF 生成器和较严格的图片库不会,而这种 bug 极难排查,因为文件「看起来」完全正常。

我的图片会被上传吗?

不会。文件通过浏览器的 File API 读取并在本地编码。当图片是内部系统的截图、尚未发布的设计稿或某份文档时,这一点值得知道。

可以把 data URI 还原成文件吗?

可以——切换到「Base64 → 图片」,粘贴完整的 data URI 或只粘后半段的 Base64,然后下载。类型会从解码出的字节重新识别,而不是采信字符串里声明的那个,所以即使 data URI 里的类型写错了也能正确保存。

SVG 有必要转 Base64 吗?

通常没必要。SVG 本身是文本,可以用 URL 编码直接嵌进 CSS,完全避开那 33% 的膨胀,而且保持可读。Base64 适合二进制格式;对 SVG 而言,它往往只是出于习惯而选的更贵的方案。