base64
约 1441 字大约 5 分钟
2026-05-03
base64能判断一个图片的大小?
Base64 的编码规则是什么?为什么能把图片编码成字符串?
const getBase64SizeKB = base64 => {
const str = base64.split(',')[1];
return ((str.length * 3) / 4 / 1024).toFixed(2); // 省略补位计算(误差<1%)
};base64核心作用
- 图片(无论 JPG/PNG)在计算机中存储、传输的原始形态是「二进制数据」(由 0 和 1 组成的字节流),这种数据无法直接在文本场景(如 JSON、HTML 文本)中展示和传输(很多协议 / 场景只支持可打印的 ASCII 字符串)。
- Base64 的核心目的:将不可直接打印的二进制数据,转换为由 64 个可打印 ASCII 字符组成的字符串,方便在文本场景中传输和存储(图片、文件、加密数据都可以用 Base64 编码)。
Base64 具体编码规则
Base64 编码的核心是「按位分组、映射替换」,步骤如下:
- 准备映射表:定义 64 个可打印字符作为编码字典(A-Z、a-z、0-9、+、/),每个字符对应一个 0-63 的索引(刚好 64 个,对应 2^6=64,即 6 个二进制位)。
- 二进制分组:将原始二进制数据(每个字节 8 位),按「每 3 个字节为一组」进行拆分(3 个字节 = 24 个二进制位)。
- 重组为 6 位一组:将 24 个二进制位,重新拆分为「4 个 6 位一组」(4×6=24 位,刚好无剩余)。
- 映射为 Base64 字符:将每个 6 位二进制数转换为十进制(范围 0-63),再去映射表中找到对应的字符,这 4 个字符就是这 3 个原始字节的 Base64 编码结果。
- 补位处理:如果原始二进制数据的字节数不是 3 的倍数,会有剩余 1 个或 2 个字节:
- 剩余 1 个字节(8 位):补 4 个 0 凑成 12 位(2 个 6 位),映射为 2 个 Base64 字符,末尾补 2 个 = 标识补位。
- 剩余 2 个字节(16 位):补 2 个 0 凑成 18 位(3 个 6 位),映射为 3 个 Base64 字符,末尾补 1 个 = 标识补位。
为什么能把图片编码成字符串?
因为图片是二进制数据,而 Base64 编码对「任何二进制数据」都适用 —— 它不关心二进制数据的内容(是图片、视频还是文本),只按上述规则对二进制字节流进行「格式转换」,最终输出由 64 个可打印字符组成的字符串,这就是图片能被编码成 Base64 字符串的原因。
Base64 怎么区分 Jpg 和 Png?为什么换一个前缀后面不换就可以?
Base64 本身不区分 Jpg 和 Png,区分图片格式的不是 Base64 编码内容,而是「Data URI 前缀」,且 Base64 编码内容与前缀是相互独立的。
我们看到的 Base64 图片字符串(data:image/png;base64,xxxx),遵循的是「Data URI 协议」,这个字符串分为两部分:
[data:][媒体类型][;base64,][Base64 编码数据]- 第一部分(前缀):
data:image/png;base64,或data:image/jpeg;base64,- 作用:告诉解析器(浏览器、图片处理工具等)“如何解析后面的字符串”,其中
image/png/image/jpeg就是「媒体类型(MIME 类型)」,明确声明了“后面的 Base64 数据解码后,是一张 Png/Jpg 图片”。
- 作用:告诉解析器(浏览器、图片处理工具等)“如何解析后面的字符串”,其中
- 第二部分:后面的字符串(Base64 编码数据)
- 作用:存储图片的二进制数据(编码后的形式),本身包含了 Png/Jpg 的原始二进制特征(文件头、像素数据等)。
解析器(如浏览器)区分图片格式时,首先会读取 Data URI 前缀的媒体类型,快速确定解析方式;即使前缀声明与实际数据格式不一致,解析器也会尝试通过解码后的二进制文件头来二次判断(比如前缀写 image/jpeg,但解码后是 Png 的文件头,浏览器依然能正常显示为 Png 图片)。
扩展: 为什么有些接口中需要将数据 base64 一下
绝大多数网络传输协议(如 HTTP 表单、JSON、XML、SMTP 邮件、URL 参数)都是「文本协议」—— 它们的设计初衷是传输可打印的 ASCII 字符(0x20~0x7E,比如字母、数字、常见符号),不支持:
二进制数据(如图片、加密密文、音频片段):包含大量非打印字符(如 0x00、0xFF),直接传输会被协议截断、转义或乱码;
特殊字符(如 URL 中的 &/=/+、XML 中的 </>/&):直接传输会被协议「误解析」(比如 URL 中的 & 会被当作参数分隔符,XML 中的 < 会被当作标签开头)。
Base64 把这些「不兼容数据」转成仅包含 A-Za-z0-9+/= 的可打印字符串,完美适配文本协议,确保数据完整传输。
体积膨胀 33%
- 原始数据:N 字节 = 8N 位;
- Base64 编码后:8N 位 ÷ 6 位 / 字符 = (4N/3) 字符;
- 膨胀比例:(4N/3 - N) / N = 1/3 ≈ 33.33%;
- 补位符=不占体积(仅标识),所以实际膨胀率 ≈33%,这是数学上的必然,无法避免。
canvas 的 DataToURI 原理是啥?
canvas.toDataURL() 的本质,是先将 Canvas 画布的位图像素数据按指定格式编码为标准图片的二进制数据,再通过 Base64 编码转为可打印的 ASCII 字符串,最终拼接成符合 RFC 2397 标准的 Data URI 链接,实现「画布绘制内容 → 标准图片文件 → 可直接嵌入网页 / 传输的 base64 字符串」的完整转换。
简单说:它不是直接把画布像素转 Base64,而是先把画布 “导出成一张标准图片”,再把图片文件转成 Base64 格式的 Data URI。