图片转 Base64

把图片编码成 data URI,或者把一段 data URI 还原成图片。两个方向都支持,中间没有服务器。

把图片拖到这里

或点击选择文件 —— 支持批量

结果在本地生成。不上传任何内容。

Base64 是什么,以及那个没人提的 33% 代价

data URI 是一种把文件塞进文档内部、而不是从外部引用它的办法。语法很短:data:image/png;base64, 后面跟上把文件字节翻译成 Base64 之后的那串文本。

这 33% 不是四舍五入的误差

Base64 用 4 个 ASCII 字符表示 3 个字节的二进制数据。这意味着一个固定、无法回避的 33% 体积增长,在任何其他考量之前就已经发生了。一张 100 KB 的 JPEG 会变成大约 137 KB 的文本。

再对比一下网络上真实发生的事:你的服务器几乎肯定已经在用 gzip 或 Brotli 压缩传输了,但Base64 文本的压缩率,远不如同等内容的优质二进制格式。现代图片格式本身就已经做过熵编码;把它转成文本再压一遍,能回收的空间比人们想象中少得多。

所以诚实的说法是:Base64 让你在原始体积上付出约三分之一,你是在用这个代价换别的东西。先确认你换到的东西值这个价。

什么情况下它真的值

  • 为关键的极小资源省掉一次请求。 首屏的 SVG sprite 或 1 KB 的 logo,内联之后就少一次往返。在高延迟的移动网络下,一次往返的代价可能远超那 300 字节。
  • 单文件交付。 邮件模板、离线 HTML 文档、要作为一个文件交出去的自包含 demo、编进二维码的页面。没有服务器的时候,也就没有东西可以链接。
  • CSS 生成的装饰。 样式表里的小背景纹理和图标字形——如果不内联,这个 URL 会相对样式表的位置去解析,然后给你一个意外的 404。

什么情况下是错的

  • 超过几 KB 的任何东西。 这份数据现在在你的 HTML 里,意味着每个引用它的页面都要重新下载一遍,它无法被独立缓存,而且——关键——它会阻塞。浏览器要解析完标记才发现内联图片;而 <img src> 是在预加载扫描阶段就被发现的。大的内联资源会推迟这个发现时机。
  • 照片,一律不要。 照片请先过一遍正经的编码器。如果你正在考虑对照片用 Base64,真正的问题通常是照片没优化,而不是它在外部。
  • 任何你希望被缓存的东西。 内联的资源与文档共存亡。页面上改一个字,用户就得连同所有内联图片一起重新下载。

几个常见的误解

Base64 不是压缩。 这是目前为止流传最广的误解。"我把图片转成 base64 让它变小"这句话从来不成立——输出永远比输入大。如果你想要的是更小,你需要更好的编码器(WebP / AVIF)或者更小的尺寸,而不是换一种文本编码。

data URI 不保密。 每一个字符在网页源码里都是明文可见的。混淆不等于加密;如果一张图片本身敏感,Base64 提供不了任何保护。

不是所有 data URI 都是 Base64。 data:image/svg+xml, 后接 URL 编码过的 SVG,是一种真实且通常更优的选择——SVG 本身就是文本,对它做百分号编码比做 Base64 编码高效得多,而且结果仍然是人类可读、对 gzip 友好的。

一条经得起实践检验的经验法则

当资源小到"请求开销占主导"时才内联——量级是个位数 KB——并且它出现在那些少一次往返确实有意义的页面上。其余一切都保持为独立的、可缓存的、编码得当的文件。精确的临界点取决于你用户的网络延迟和你的缓存头配置,所以把它当作待验证的初始假设,去测,而不是当成定律。

常见问题

为什么我的文件反而变大了?
因为 Base64 一定会让文件变大,通常是三分之一左右。它是编码方式,不是压缩算法。如果你的目标是让图片更小,请用图片压缩工具,或转成 WebP / AVIF。
能编码多大的文件?
本工具不设限制,实际的瓶颈是你浏览器的内存。要注意的是:极长的字符串粘进编辑器会很卡,而且很多 Web 服务器和 CDN 对文档大小各有各的限制。
能把 data URI 还原成文件吗?
可以。切到解码模式,把整段 data URI 粘进去,包含 data:image/png;base64, 这个前缀。工具会读取其中声明的 MIME 类型,解码数据,把图片还原成可下载的文件。
SVG 能用吗?
能。但对 SVG 来说,把源码做 URL 编码通常比做 Base64 编码小得多,因为 SVG 本身就是文本。建议先用 SVG 压缩工具精简一遍源码。
data URI 安全吗?
它不提供任何保密性——任何能看到源码的人都能轻松解码。此外还有一个注入风险:永远不要把用户提交的内容拼成 data URI 再赋给 srchref,除非你校验过 MIME 类型,因为 data:text/html 这类 URI 是可以携带脚本的。