图片转 Base64:何时以及如何使用 Data URI

·

什么是 Base64 编码

Base64 是一种将二进制数据转换为 ASCII 字符串的编码方式。它使用 64 个可打印字符(A-Z、a-z、0-9、+、/)来表示任意二进制数据,让图片这样的二进制文件能够以文本形式嵌入到 HTML、CSS 或 JSON 中。

编码原理

Base64 将每 3 个字节的二进制数据转换为 4 个 ASCII 字符。由于这种 3:4 的转换比例,编码后的字符串比原始数据大约 33%。

原始数据:  3 字节 = 24 位
Base64 编码:4 字符 × 6 位 = 24 位

Data URI 格式

将 Base64 编码的图片嵌入网页时,使用 Data URI 格式:

data:[<mediatype>][;base64],<data>

例如一张 PNG 图片的 Data URI:

data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==

何时使用 Base64 图片

Base64 内联图片在特定场景下有明显优势,但并非所有情况都适用。

适合使用 Base64 的场景

场景优势说明
HTML 邮件避免外部引用邮件客户端对外部图片限制严格
CSS 小图标减少 HTTP 请求小于 4KB 的图标内联更高效
单文件 HTML便于分发所有资源打包在一个文件中
SVG 数据矢量图形内联SVG 本身就是文本格式
API 响应简化传输无需额外下载图片资源

不适合使用 Base64 的场景

场景原因替代方案
大图片文件增大 33%,影响加载使用 WebP/JPEG 文件
需要缓存的图片无法被浏览器单独缓存使用独立图片文件
频繁修改的图片每次修改需重新编码使用外部图片文件
SEO 重要的图片搜索引擎难以索引使用带 alt 的 img 标签
移动端大图增加内存占用使用响应式图片

Base64 对文件大小的影响

Base64 编码会使文件大小增加约 33%,这是由编码原理决定的。

大小对比示例

原始大小Base64 大小增加量增加比例
1 KB1.33 KB0.33 KB33%
10 KB13.3 KB3.3 KB33%
100 KB133 KB33 KB33%
1 MB1.33 MB330 KB33%

为什么是 33%

Base64 将 3 个字节编码为 4 个字符,即 4/3 ≈ 1.33 倍。对于不是 3 的倍数的数据,末尾会添加 = 填充字符,所以实际增加可能略大于 33%。

对性能的综合影响

虽然文件大小增加了 33%,但在某些情况下整体性能反而更好:

  • 小图片:省去一次 HTTP 请求的开销(通常 50-200ms)
  • HTTPS 页面:减少 TLS 握手次数
  • HTTP/1.1:避免连接数限制

经验法则:小于 4KB 的图片适合 Base64 内联,大于 4KB 的图片应该使用独立文件

如何使用 PicKit 转换

PicKit 图片转 Base64 工具 可以快速将图片转换为 Base64 编码的 Data URI。

操作步骤

  1. 上传图片:点击上传或拖放图片到页面
  2. 自动转换:工具自动生成 Base64 编码
  3. 选择输出格式
    • 纯 Base64 字符串
    • 完整 Data URI(带 data:image/... 前缀)
    • CSS background-image 格式
    • HTML img 标签格式
  4. 复制使用:点击复制按钮,粘贴到代码中

支持的输入格式

格式输出 MIME 类型适用场景
PNGimage/png带透明度的图标
JPEGimage/jpeg照片类图片
WebPimage/webp现代格式
GIFimage/gif简单动画
SVGimage/svg+xml矢量图形
BMPimage/bmp旧格式兼容

代码示例

在 CSS 中使用 Base64 图片

/* 小图标作为背景 */
.icon-home {
  width: 16px;
  height: 16px;
  background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4wYCEw4Y9t6m8wAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAAAJUlEQVQ4y2NgGAXUBgY/jwzA8B8v8QAxzDAAGwCDMwMDCBQVRgYAAF0mAwA7cQMyJQAAAABJRU5ErkJggg==');
  background-size: contain;
  background-repeat: no-repeat;
}

/* 伪元素装饰 */
.button::before {
  content: '';
  display: inline-block;
  width: 12px;
  height: 12px;
  margin-right: 6px;
  background-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMiIgaGVpZ2h0PSIxMiI+PC9zdmc+');
}

在 HTML 中使用 Base64 图片

<!-- 直接作为 img src -->
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4wYCEw4Y9t6m8wAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAAAJUlEQVQ4y2NgGAXUBgY/jwzA8B8v8QAxzDAAGwCDMwMDCBQVRgYAAF0mAwA7cQMyJQAAAABJRU5ErkJggg=="
     alt="首页图标"
     width="16"
     height="16">

<!-- 在 picture 标签中使用 -->
<picture>
  <source srcset="data:image/webp;base64,UklGRiQAAABXRUJQVlA4IBgAAAAwAQCdASoBAAEAAQAmJaQAA3AA..." type="image/webp">
  <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA..." alt="描述文字">
</picture>

在 JavaScript 中动态生成

// 将 File 对象转换为 Base64
function fileToBase64(file) {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.onload = () => resolve(reader.result);
    reader.onerror = reject;
    reader.readAsDataURL(file);
  });
}

// 使用示例
const input = document.querySelector('input[type="file"]');
input.addEventListener('change', async (e) => {
  const file = e.target.files[0];
  const base64 = await fileToBase64(file);
  console.log(base64); // data:image/jpeg;base64,...
});

在 HTML 邮件中使用

<!-- 邮件中的内联图片 -->
<table width="600" cellpadding="0" cellspacing="0">
  <tr>
    <td style="padding: 20px; text-align: center;">
      <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4wYCEw4Y9t6m8wAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAAAJUlEQVQ4y2NgGAXUBgY/jwzA8B8v8QAxzDAAGwCDMwMDCBQVRgYAAF0mAwA7cQMyJQAAAABJRU5ErkJggg=="
           alt="Logo"
           width="100"
           style="display: block; margin: 0 auto;">
    </td>
  </tr>
</table>

Base64 与缓存策略

浏览器缓存问题

使用 Base64 内联的图片无法被浏览器单独缓存。每次加载包含该 Base64 字符串的 HTML 或 CSS 文件时,图片数据都会重新下载。

缓存方式独立图片文件Base64 内联图片
浏览器缓存✓ 可单独缓存✗ 随父文件缓存
CDN 缓存✓ 可单独缓存✗ 随父文件缓存
跨页面复用✓ 多页面共享✗ 每个页面重复
修改更新✓ 只更新图片✗ 需更新父文件

推荐的缓存策略

  • 小图标:Base64 内联到 CSS 中,CSS 文件本身可被缓存
  • 大图片:使用独立文件,配合长期缓存和文件名哈希
  • 频繁更新:使用独立文件,避免每次修改都重新编码

优化 Base64 使用

先压缩再编码

在转换为 Base64 之前,先将图片压缩转换为 WebP 格式,可以显著减小 Base64 字符串的长度。

优化步骤文件大小Base64 大小
原始 PNG50 KB66.5 KB
压缩后 PNG35 KB46.5 KB
转 WebP 后25 KB33.3 KB

使用 Gzip 压缩

服务器开启 Gzip 或 Brotli 压缩后,Base64 字符串的传输大小可以减少 70-80%,因为 Base64 字符的重复模式非常适合压缩。

原始大小Base64 大小Gzip 后大小
10 KB13.3 KB4-5 KB
50 KB66.5 KB20-25 KB

常见问题

Base64 图片会影响 SEO 吗? Base64 编码的图片在 <img> 标签中仍然可以设置 alt 属性,搜索引擎可以读取替代文本。但搜索引擎爬虫可能不会单独索引 Base64 图片,对于重要的展示图片,建议使用独立文件并配合描述性文件名。

Base64 编码后的图片如何解码还原? 使用 PicKit 图片转 Base64 工具 可以双向转换。在代码中,JavaScript 可以使用 atob() 函数解码 Base64 字符串,或使用 fetch() 将 Data URI 转换为 Blob 对象。

为什么我的 Base64 字符串特别长? Base64 字符串长度与图片文件大小成正比。如果字符串过长,说明图片文件较大。建议先压缩图片调整尺寸减小文件大小,再进行 Base64 编码。

Base64 图片能在所有浏览器中显示吗? 现代浏览器都支持 Data URI。IE8 及以下版本有 32KB 的大小限制,IE9+ 支持但限制为 4GB。目前所有主流浏览器(Chrome、Firefox、Safari、Edge)都没有实际限制。

Data URI 和 Blob URL 有什么区别? Data URI 将图片数据直接编码到 URL 中,适合小图片和需要持久化的场景。Blob URL 是指向内存中 Blob 对象的引用,适合动态生成的大图片,但页面刷新后会失效。对于静态小图标,Data URI 更合适。