什么是Base64?图片怎么转换为Base64编码?
你是否想过,为什么一张图片可以变成一串看起来毫无意义的乱码字符串,却还能在网页上正常显示?这背后的魔法,就是 Base64编码。
从邮件附件到网页内嵌图片,从API数据传输到小程序图片处理,Base64几乎无处不在。它不是加密算法,却让二进制数据在文本世界里自由穿行。而图片转Base64,更是前端开发、数据传输中最常用的技能之一。
本文将从原理到实操,从代码到命令行,把Base64和图片转换这件事讲透。
一、什么是Base64?一句话讲清本质
Base64是一种基于64个可打印字符来表示任意二进制数据的编码方法。
它的核心目的只有一个:让二进制数据(图片、文件、视频)能在只支持文本的环境中安全传输。
比如早期的邮件系统只支持ASCII字符,你没法直接在邮件正文里塞一张图片。但如果把图片编码成一串由字母、数字和符号组成的文本,邮件系统就能正常处理了——这就是Base64诞生的原因。
Base64最早应用于邮件传输协议(MIME),在RFC 2045~RFC 2049中被完整定义和标准化。
二、Base64的字符集:64个字符,一个不多一个不少
Base64使用的字符集非常固定,一共64个可打印字符:
| 类别 | 字符范围 | 数量 |
|---|---|---|
| 大写字母 | A~Z | 26个 |
| 小写字母 | a~z | 26个 |
| 数字 | 0~9 | 10个 |
| 特殊符号 | + 、/ | 2个 |
| 合计 | — | 64个 |
此外还有一个 "=" 符号,它不属于索引表,专门用于填充(Padding),确保编码结果的长度是4的倍数。
为什么是64个? 因为2的6次方等于64(2⁶=64),每6个比特(bit)可以表示64种状态,正好对应64个字符。这就是"Base64"名字的由来——64进制。

三、Base64编码规则:3字节变4字符
这是整篇文章最核心的部分,理解了这个规则,你就理解了Base64的全部。
核心转换逻辑
| 步骤 | 说明 |
|---|---|
| 第1步 | 把原始二进制数据每3个字节(3×8=24位)分为一组 |
| 第2步 | 把这24位重新划分为4组,每组6位(4×6=24位) |
| 第3步 | 每6位作为一个索引值,查Base64索引表,得到对应字符 |
| 第4步 | 如果原始数据不是3的倍数,用 "=" 补齐到4的倍数 |
举个例子:编码 "Man"
| 字符 | ASCII码 | 二进制 |
|---|---|---|
| M | 77 | 01001101 |
| a | 97 | 01100001 |
| n | 110 | 01101110 |
三个字节共24位,划分为4个6位组:
| 6位组 | 二进制 | 十进制索引 | Base64字符 |
|---|---|---|---|
| 第1组 | 010011 | 19 | T |
| 第2组 | 010110 | 22 | W |
| 第3组 | 000101 | 5 | F |
| 第4组 | 101110 | 46 | u |
所以 **"Man" → "TWFu"**,3个字符变成了4个字符。
填充规则(Padding)
当原始数据字节数不是3的倍数时:
| 原始字节数 ÷ 3 的余数 | 编码后字符数 | 补几个"=" |
|---|---|---|
| 余0(正好整除) | 4的倍数 | 0个 |
| 余1 | 需补2个"=" | "==" |
| 余2 | 需补1个"=" | "=" |
例如:"abcd"(4字节,余1)→ 编码为 **"YWJjZA=="**,末尾两个等号就是填充。
Base64编码后的数据长度比原始数据约多1/3(约33%),这是它最大的代价。
四、图片怎么转换为Base64编码?5种方法全覆盖
图片本质上就是二进制文件,转换为Base64的过程就是:读取图片的二进制数据 → 用Base64算法编码 → 输出字符串。
以下5种方法覆盖了几乎所有使用场景。
方法1:Python(最推荐,最灵活)
Python内置了base64模块,3行代码即可完成:
import base64
with open("photo.jpg", "rb") as f:
encoded = base64.b64encode(f.read()).decode("utf-8")
print(encoded)关键注意事项:
| 要点 | 说明 |
|---|---|
| 必须用"rb"模式打开 | base64.b64encode()只接受bytes,用"r"模式会报TypeError |
| .decode("utf-8") | 把编码结果从bytes转为字符串,方便在HTML中使用 |
| 大图要分块读 |
20MB以上的图片,一次性f.read()会占用双倍内存(原始+编码后),建议用base64.encodebytes()分块处理 |
如果需要带MIME前缀(用于HTML img标签):
import base64
with open("photo.jpg", "rb") as f:
encoded = base64.b64encode(f.read()).decode("utf-8")
mime_type = "image/jpeg" # 或 image/png
result = f"data:{mime_type};base64,{encoded}"
print(result)
输出格式:data:image/jpeg;base64,/9j/4AAQSkZJRgABAQE...
方法2:JavaScript / 浏览器端(前端最常用)
在浏览器中,使用FileReader API可以将用户上传的图片直接转为Base64:
<input type="file" id="img_upload" accept="image/*">
<textarea id="base64_code" rows="10" cols="60"></textarea>
<script>
document.getElementById("img_upload").addEventListener("change", function() {
var file = this.files[0];
var reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = function() {
document.getElementById("base64_code").value = this.result;
};
});
</script>核心逻辑: reader.readAsDataURL(file)会自动完成"读取二进制→Base64编码→添加data:前缀"的全过程。
方法3:Go语言(后端/服务端场景)
Go标准库encoding/base64提供了简洁的实现:
package main
import (
"encoding/base64"
"fmt"
"io/ioutil"
"net/http"
)
func main() {
bytes, _ := ioutil.ReadFile("./flower.jpg")
mimeType := http.DetectContentType(bytes)
var prefix string
switch mimeType {
case "image/jpeg": prefix = "data:image/jpeg;base64,"
case "image/png": prefix = "data:image/png;base64,"
}
encoded := prefix + base64.StdEncoding.EncodeToString(bytes)
fmt.Println(encoded)
}
Go的优势在于处理远程图片也非常方便,只需先http.Get()获取图片二进制数据,再进行编码即可。
方法4:命令行(最快,无需写代码)
如果你只是临时需要转换一张图片,命令行是最快的方式:
| 系统 | 命令 |
|---|---|
| Linux / macOS | base64 -i image.png -o image_base64.txt |
| Windows PowerShell | [Convert]::ToBase64String([IO.File]::ReadAllBytes("image.png")) |
Linux的base64命令会直接把编码结果输出到文件或终端,零学习成本。
方法5:在线转换工具(零代码,最省事)
不想写代码也不想开终端?直接用在线工具:
如福娃工具网的在线图片转Base64工具:https://www.fuwa.org/tools/imgtobase64.html
上传图片 → 自动生成Base64字符串 → 复制使用

五、Base64怎么转回图片?解码同样简单
编码是"图片→字符串",解码就是反过来:
| 语言 | 解码代码 |
|---|---|
| Python | base64.b64decode(encoded_str),然后用open("out.jpg","wb").write(data)写入文件 |
| JavaScript | atob(base64_str)得到二进制字符串,再转成Blob或Uint8Array |
| Go | base64.StdEncoding.DecodeString(encoded_str) |
关键提醒: 如果Base64字符串缺少末尾的"="填充,解码前必须手动补全:
missing_padding = len(encoded_str) % 4 if missing_padding: encoded_str += "=" * (4 - missing_padding)
否则b64decode()会抛出binascii.Error: Incorrect padding错误。
六、Base64图片的优缺点:什么时候该用,什么时候不该用
| 维度 | 优点 | 缺点 |
|---|---|---|
| 体积 | 减少HTTP请求数量(一张图=一个请求) | **体积增加约33%**,大图传输更慢 |
| 缓存 | 无需额外请求,首屏加载快 | 无法被CDN缓存,每次访问都重新下载 |
| 兼容性 | 任何支持文本的地方都能用 | 不支持懒加载,data URL立即解析 |
| 调试 | 图片和HTML在一起,方便管理 | 浏览器DevTools中看不到图片的尺寸、加载时间等信息 |
结论非常明确:
✅ 适合用Base64的场景:小图标(<10KB)、少量装饰图片、需要内嵌到JSON/CSS中的图片
❌ 不适合的场景:大图(>50KB)、需要缓存的图片、大量图片的页面
一张20MB的PNG图片,经Base64编码后体积约26MB,且Python会同时在内存中保存原始bytes和编码后字符串——实际内存占用超过50MB。对服务端来说,这是实实在在的性能杀手。
七、实战对比:三种Python方式转换图片与Base64
| 方式 | 核心代码 | 适用场景 | 优缺点 |
|---|---|---|---|
| 直接读取文件 | open(path,"rb").read() | 小图片,最简单 | ✅ 最简洁 ❌ 大图内存爆炸 |
| PIL/Pillow | Image.open() → BytesIO → b64encode | 需要先处理图片(裁剪、压缩) | ✅ 可预处理 ❌ 多一层依赖 |
| OpenCV | cv2.imencode() → tobytes() → b64encode | 需要指定输出格式/质量 | ✅ 可控质量 ❌ 依赖cv2库 |
代码示例(PIL方式):
from io import BytesIO
from PIL import Image
import base64
def image_to_base64(image_path):
image = Image.open(image_path)
buffer = BytesIO()
image.save(buffer, format="JPEG")
return base64.b64encode(buffer.getvalue()).decode("utf-8")八、微信小程序中图片转Base64的三种方案
小程序开发中,图片转Base64是高频需求,主要有三种实现路径:
| 方案 | 核心API | 优点 | 缺点 |
|---|---|---|---|
| wx.getFileSystemManager().readFile() | encoding: 'base64' | 🚀 性能最优,代码最简 | ⚠️ 仅支持本地文件 |
| Canvas绘制转换 | canvas.toDataURL() | ✅ 可裁剪/加水印/滤镜 | ❌ 代码复杂,有绘制延迟 |
| wx.request + ArrayBuffer | wx.arrayBufferToBase64() | ✅ 支持网络图片 | ❌ 受域名白名单限制 |
最推荐的方案是readFile,一行核心代码搞定:
wx.getFileSystemManager().readFile({
filePath: tempFilePath,
encoding: 'base64',
success: (res) => {
this.setData({ base64: `data:image/png;base64,${res.data}` });
}
});九、常见问题速答
Q:Base64是加密算法吗?
不是。 Base64只是一种编码方式,数据从一种形式转换为另一种形式,任何人都可以解码。它不能用于保护数据安全。
Q:为什么有些Base64字符串末尾没有"="?
因为有些场景(如URL传输)中"="会造成歧义,所以部分实现会自动去掉填充符。解码时需要手动补全。
Q:Base64和Base64URL有什么区别?
标准Base64使用"+/"两个字符,而Base64URL把"+/"替换成"-_",因为"+/"在URL中会被编码为"%XX"形式,造成额外麻烦。Python中可用base64.urlsafe_b64encode()实现。
Q:图片转Base64后,怎么在HTML中使用?
直接放在img标签的src属性中:
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA...">
写在最后
Base64不神秘,它就是一套把二进制翻译成文本的规则。3字节变4字符,64个可打印字符轮流出场,末尾不够就用"="补齐——就这么简单。
图片转Base64的核心也只有一句话:读取图片的二进制数据,然后用Base64算法编码。Python三行代码,JavaScript一个API,命令行一条指令,都能搞定。
但请记住它的代价:体积增加33%,无法缓存,不支持懒加载。小图用它锦上添花,大图用它雪上加霜。
选对工具,用对场景,Base64就是你手中最顺手的那把瑞士军刀。
版权及免责申明:本文由@fuwa原创发布。该文章观点仅代表作者本人,不代表本站立场。本站不承担任何相关法律责任。
如若转载,请注明出处:https://www.fuwa.org/tutorials/33.html

