图片转 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——并且它出现在那些少一次往返确实有意义的页面上。其余一切都保持为独立的、可缓存的、编码得当的文件。精确的临界点取决于你用户的网络延迟和你的缓存头配置,所以把它当作待验证的初始假设,去测,而不是当成定律。
常见问题
为什么我的文件反而变大了?
能编码多大的文件?
能把 data URI 还原成文件吗?
data:image/png;base64, 这个前缀。工具会读取其中声明的 MIME 类型,解码数据,把图片还原成可下载的文件。SVG 能用吗?
data URI 安全吗?
src 或 href,除非你校验过 MIME 类型,因为 data:text/html 这类 URI 是可以携带脚本的。