图片转Base64转换器

选一张本地图片,转成可以直接写进 HTML 或 CSS 的 Data URL,同时算清它比原文件大了多少、这张图到底该内联还是该走外链。

也可以把图片直接拖到这里释放

提示:在「内联体积阈值」或「复用次数」输入框里按 Enter 即可重算;页面打开时结果区是内置的 1×1 透明 PNG 示例(68 字节),点「载入示例」可随时还原。

使用方法

  1. 点「选择图片」,或把文件直接拖到虚线框里。页面打开时结果区已经放了一个 1×1 透明 PNG 的 Data URL 作为示例,它不是空框。
  2. 看统计条里的原始字节与 Base64 字符数:示例图是 68 字节 → 92 个字符,完整 Data URL 长度 114 字节。
  3. 「内联体积阈值」默认 2 KB。图片原始字节不超过阈值、且复用次数为 1 时,工具给出「建议内联」;超过阈值就改为「建议外链」。
  4. 「同一张图站内复用次数」填这张图会被几个页面用到。填 2 以上时,无论图片多小都建议走外链——独立文件能被浏览器单独缓存,第二次访问是 0 字节。
  5. 在「输出形态」里选你要粘贴的代码:完整 Data URL、纯 Base64、CSS 的 background-image,或一段 <img> 标签。选完立刻重算。
  6. 点「复制结果」带走文本,或点「下载 .txt」存成 UTF-8 文本文件。阈值和复用次数框里按 Enter 也能重算。

这个图片转Base64转换器能解决什么问题

一是把首屏小图从请求里拿掉。图标、分隔线、加载动画这类不到 1 KB 的图,每个都会占掉一次 HTTP 请求。HTTP/1.1 下浏览器对同一域名只开 6 条并发连接,24 张这样的小图要排队 4 轮;把它们内联,请求数直接归零。

二是单文件分发。把 CSS 连同其中的小图标一起发给同事、贴进邮件、塞进只有一份文件的静态页时,Data URL 让整个资源不依赖任何外部路径,不会出现「图裂了」。

三是算清代价再决定。Base64 会把体积撑大约三分之一,很多人在没算之前就先把几百 KB 的配图内联进去,结果 HTML 涨到几 MB。本工具把原始字节、编码字符数、膨胀率、阈值判断放在同一屏,一眼就能看出这张图值不值得内联。

四是给后端和第三方接口准备素材。不少接口(例如图片识别、图表 API)要求把图片以 Base64 字符串放在 JSON 字段里,这时需要的是不带 data: 前缀的纯 Base64,直接切到「纯 Base64 字符串」形态即可。

本页不做这些事:不做压缩、不缩放、不裁剪、不转格式。要压缩体积请用「图片压缩工具」,要换格式请用「图片格式转换」或「WebP转PNG转换器」。反向操作——把一段 Base64 还原成图片——请用底部的「Base64转图片转换器」。

编码原理:readAsDataURL、4/3 膨胀与 Data URL 前缀

这个图片转Base64转换器在读取环节调的是 FileReader.readAsDataURL(file),这是 W3C File API 定义的接口,不是自己写的编码器。它返回的字符串形如 data:image/png;base64, 后面接 Base64 正文。之所以不用 readAsArrayBuffer 再手动转,是因为前者由浏览器原生完成读取与编码,省掉一次全量字节数组的内存驻留;代价是拿到的字符串无法流式处理,必须先完整读进内存,这也是本页把上限设在 20 MB 的原因。

Base64 编码本身由 RFC 4648 定义。它把每 3 个字节(24 位)重新切成 4 组 6 位,每组映射到字母表 A–Z a–z 0–9 + / 里的一个字符。24 位刚好装下 4 个 6 位,所以 3 字节进、4 字符出——这就是 4/3 的来历。字节数不是 3 的倍数时用 = 补齐:余 1 字节补 2 个 =(该字节只贡献 12 位有效数据),余 2 字节补 1 个 =。所以哪怕只有 1 个字节,输出也是 4 个字符。长度公式是 4 × Math.ceil(n / 3),以字节为单位向上取整,本页统计条里的 Base64 字符数用的就是它。

4/3 = 33.33% 是下限而不是典型值。只有当字节数恰好是 3 的倍数时才精确等于 33.33%;100 字节的图要膨胀 36.00%,256 字节是 34.38%,2 KB 是 33.40%。所谓「大约大三分之一」是把填充开销摊薄之后的说法,小图的实际膨胀率更高。除了正文,Data URL 还要多带一个前缀:data:image/png;base64, 是 22 字节,data:image/jpeg;base64, 与 data:image/webp;base64, 是 23 字节,data:image/svg+xml;base64, 是 26 字节。

为什么阈值默认取 2 KB,而不是 10 KB 或 100 KB。这条线来自「省掉一次请求能省多少」与「HTML 变大要多久」的对比。内联省掉的是一个完整往返,包含 DNS、TCP、TLS 与服务器处理,在移动网络下通常落在一百毫秒量级;而多传的字节在同一个响应里,且 gzip 之后几乎被吃回去。实测把 2 KB 的已压缩图像(PNG/JPG 这类不可再压的数据)编成 Base64 再 gzip,只有 2.34% 的净增;10 KB 时降到 0.69%。也就是说 gzip 打开后,内联的体积代价基本可以忽略,真正的代价变成了「无法单独缓存」和「阻塞 HTML 解析」。所以判据不是单纯的体积,而是这张图会不会被复用:用完一次的小图内联,多页面复用的图一律外链。

gzip 为什么能把 Base64 压回去。Base64 字母表只有 64 个符号,每个字符承载 6 bit 信息,而 UTF-8 里它占 8 bit,天然多了 2 bit 的冗余,gzip 的熵编码正好把它挤掉。但无论如何也回不到原始二进制的大小——上面那 2.34% 与 0.69% 就是这个差值。而 SVG 这类本身是纯文本的资源是另一回事:示例里的 135 字节 SVG 源码 base64 后是 180 字符,gzip 原始源码是 122 字节,gzip 后的 Base64 是 169 字节——对 SVG 而言,内联 Base64 反而比直接内联源码更差,能内联源码就别转 Base64。

完整示例(数值仅作演示)

示例条件与页面打开时的默认值一致:内置那张 1×1 透明 PNG 共 68 字节,阈值 2 KB,复用次数 1,输出形态为完整 Data URL。

把同一套公式套到一张 2 KB 的配图上又是另一种结论:

输入范围与大小对照表

下表按上面的公式逐档算出,用于判断某个体积的图内联后会把页面撑大多少。「建议」一列取默认阈值 2 KB、复用次数 1。

图片原始大小Base64 字符数完整 Data URL 字节相对原始膨胀默认阈值下的建议
68 B(页内示例图)9211435.29%内联
100 B13615836.00%内联
256 B34436634.38%内联
512 B68470633.59%内联
768 B1024104633.33%内联
1 KB1368139033.59%内联
2 KB2732275433.40%内联

三个输入项各自的允许范围:内联体积阈值 0.1~512 KB(步长 0.1,按 1 KB = 1024 字节换算成字节后与图片原始字节比较);复用次数 1~500 的整数(只影响建议,不影响编码结果);文件体积 ≤ 20 MB,20 MB 按公式会得到 27962028 个 Base64 字符,完整 Data URL 约 27962050 字节。

结果边界、舍入与常见误用

常见问题

为什么转出来一定比原图大三分之一?

因为 Base64 每个字符只承载 6 位数据,而它在 UTF-8 里要占 8 位,3 字节变 4 字符是最省的结果,也就是 4/3。字节数不是 3 的倍数时还要补 =,小图的实际膨胀更大:100 字节的图要涨 36.00%,1 字节的图甚至会涨到 300%。

开了 gzip 是不是就不膨胀了?

接近但不等于零。Base64 只有 64 个符号,冗余能被 gzip 挤掉大半。实测把已压缩的图片数据编成 Base64 再 gzip:2 KB 时净增 2.34%,10 KB 时净增 0.69%。也就是说 gzip 之后体积基本不是问题,能不能单独缓存才是决定因素。

SVG 图为什么不适合转 Base64?

因为 SVG 是纯文本,gzip 对它的压缩率本来就高。示例中 135 字节的 SVG 源码 gzip 后是 122 字节,而先转 Base64 再 gzip 是 169 字节——转一道反而更大。SVG 建议直接内联源码,或作为独立文件走外链。

同一个图标在 5 个页面都用到,该内联吗?

不该。把「复用次数」填 5,工具会直接给出外链建议。内联的字符串会完整复制进 5 份 HTML,用户第一次访问第 2、3 个页面时要重复下载;独立文件则命中浏览器缓存,后续页面是 0 字节。

Base64 能当加密用吗?

不能。它是公开的编码格式,没有密钥也不做混淆,拿到字符串就能还原出原始字节。需要保密请用 HTTPS 传输、用访问控制限制图片,或者对文件本身做加密后再编码。

输出里的 data: 前缀能删掉吗?

要看用在哪里。写进 <img src> 或 CSS 的 url() 时必须带完整前缀,否则浏览器不认;但如果是提交给要求「纯 Base64 字段」的接口或写进 JSON,就要切到「纯 Base64 字符串」形态,前缀留着会让对方解码失败。

为什么限制 20 MB,超了怎么办?

因为 readAsDataURL 要把整个文件读成字符串,20 MB 的图会生成约 2796 万个字符,写进 HTML 会让首屏明显变慢。超限时先压缩:用「图片压缩工具」或「压缩图片转100KB」把体积降到几百 KB 以内再回来转。

转出来的字符串里出现 = 是出错了吗?

不是。末尾的 = 是 RFC 4648 规定的填充符,用来把不足 3 字节的尾部补成一个完整的 4 字符组:余 1 字节补 2 个,余 2 字节补 1 个。它是编码的一部分,删掉反而会让解码器报错。

相关工具