使用方法
- 把 base64 内容粘进输入框。两种形态都认:完整的 Data URL(以
data:image/png;base64,开头),或不含前缀的纯 base64 字符串。打开页面时已预置一张 10×10 的示例 PNG,点「解码预览」直接出图。 - 点「解码预览」或按 Ctrl / Cmd + Enter。Base64转图片转换器会在右侧显示图片,信息栏给出嗅探类型、解码后 78 字节、base64 长 104 字符这三组数。
- 点「下载图片」把解码结果存成 .png 文件——嗅探出什么类型就存什么扩展名,与 Data URL 里声明的是什么无关。
- 解码失败时看红色错误区:会指出第一个非法字符的位置、缺没缺补位 =、或者声明 MIME 与魔术字节是否矛盾。
- 想核对一个串是什么格式但不需要预览,直接看下方魔术字节对照表,前几个十六进制字节对上哪行就是哪行。
Base64转图片转换器能解决什么问题
第一个场景是调试内嵌图片。CSS 里 background-image:url(data:image/png;base64,…) 或接口返回的 base64 字段到底是不是一张合法图、是什么格式,粘进来立刻见分晓——尤其当声明的 MIME 是猜的、复制时丢了尾巴的时候,本页会明确告诉你哪一环断了。
第二个场景是恢复图片文件。手里只有一段 base64(日志、数据库字段、前端传参)需要还原成 .png/.jpg 文件时,下载按钮按嗅探结果给正确的扩展名,而不是盲信来源标注。
第三个场景是校验「声明与内容一致」。把 Content-Type 标成 image/png 实际塞了 HTML 的响应是常见的安全问题,本页按字节而不是按声明判定类型,声明与嗅探不符会直接报错。
本页只做「base64 → 图片」这一个方向。要把图片编码成 base64,走反方向的图片转Base64转换器;只做文本与 base64 互转的走Base64URL编码解码,那页处理的是文本编码不是二进制图片。
原理与规则说明
Data URL 的结构由 RFC 2397 定义:data:image/png;base64, 三段——「data:」协议头、MIME 类型、「;base64」编码标记,逗号之后才是数据。缺逗号、缺 base64 标记都会被逐条拦截;URL 编码形态(data:,xxx)属于另一套语法,本页不处理。
解码链路是 atob → 二进制字符串 → Uint8Array。atob() 的返回值是「每个字符码位 0-255 的字符串」,不是字节数组,直接把它当图片数据用必然出错。必须经 Uint8Array.from(bin, c => c.charCodeAt(0)) 逐字符取码位转成字节数组,再包进 Blob。字符数等于字节数这一步可以用来核对:示例载荷 104 字符,解码后正好 78 字节。
字节量按 RFC 4648 换算:字节数 = base64 长度 × 3/4 − 补位「=」个数。每 3 个字节编码成 4 个字符,这就是 base64 体积恒定膨胀 4/3 ≈ 133.33% 的来源——示例 78 字节膨胀成 104 字符,104/78 = 1.3333,分毫不差。
类型判定靠魔术字节嗅探,不信任声明。PNG 前 8 字节固定是 89 50 4E 47 0D 0A 1A 0A(十进制 137 80 78 71 13 10 26 10),JPEG 是 FF D8 FF,示例串解码后前 8 字节正好是这组数,所以判定为 image/png。PNG 的宽高也不要解析器猜:IHDR 块的第 16-19 字节是宽、20-23 字节是高,按大端序(network byte order)读,这是 PNG 规范强制的字节序,示例读出 10×10。
预览用 Blob URL:URL.createObjectURL(new Blob([bytes], { type: 嗅探结果 })) 生成 blob: 链接交给 <img>。每次解码都会新建一个 Blob 占住内存,所以本页在下次解码和换示例时对上一次的 URL 调 revokeObjectURL 释放。
完整示例(数值仅作演示)
预置示例是一张真实的 10×10 像素 PNG,整条 Data URL 已写在输入框里:
- 逗号位置 21,逗号前是
data:image/png;base64,载荷 104 字符、无补位(78 恰好是 3 的倍数,不需要 =) - 按 RFC 4648 复核:104 × 3/4 − 0 = 78 字节;膨胀比 104/78 = 1.3333,即 +33.33%
- atob 产出 78 字符的二进制字符串,转 Uint8Array 后前 8 字节 = [137, 80, 78, 71, 13, 10, 26, 10],命中 PNG 签名
- 读 IHDR:宽 = 字节 16-19 大端序 = 10,高 = 字节 20-23 = 10,与实际渲染尺寸一致
这三个数字(104、78、10×10)与解码后的图片三处互相咬合:字符数、字节数、像素宽高,换任何一张 PNG 都能用同一套公式验算。
输入范围与对照表
本页接受两种输入形态;载荷长度必须是 4 的倍数(RFC 4648 的填充规则),字符集限 A-Z a-z 0-9 + / 与末尾补位 =。解码结果超过 2 MB(对应 base64 长 2796204 字符)直接拒绝——atob 处理兆级字符串会卡住标签页数秒。嗅探按下方表序短路匹配,前两字节就足够区分 JPEG/PNG/GIF/BMP 这四类高频格式:
| 格式 | 前几字节(十进制) | 十六进制 |
|---|---|---|
| PNG | 137 80 78 71 | 89 50 4E 47 |
| JPEG | 255 216 255 | FF D8 FF |
| GIF | 71 73 70 56 | 47 49 46 38 |
| BMP | 66 77 | 42 4D |
| WebP | 82 73 70 70 …(偏移 8) | 52 49 46 46 … 57 45 42 50 |
| ICO | 0 0 1 0 | 00 00 01 00 |
完整 14 行对照表在工具区,含 TIFF 双字节序、AVIF/HEIC 的 ftyp box 与「看着像图但被拒绝」的 PDF/PSD,默认 12 行、可加载更多、可导出 CSV。
输入范围、边界与精度说明
声明 MIME 与嗅探结果不一致是硬报错,不是警告。data:image/png 声明后面跟一段 JPEG 字节,说明这条串在生成或传输中被动过手脚;直接预览等于替坏数据背书。本页的报错会同时给出两个值让你自查来源。
URL-safe base64 不认。Base64URL 变体把 + 换成 -、/ 换成 _(RFC 4648 第 5 节),用于 URL 场景。本页按标准字母表校验,遇到 - 或 _ 会指出第几个字符非法并提示先替换回 + 和 /——因为图片数据的来源通常是标准编码,静默兼容两种字母表反而掩盖「串被 URL 处理污染」的事实。
补位的两种病:长度不是 4 的倍数(漏抄字符),或 = 出现在中间(复制时混入换行处理错误)。atob 对前者直接抛 InvalidCharacterError,本页把它翻译成「检查是否漏抄了末尾的 =」。空白字符(换行、空格)会被静默剥除——邮件、JSON 里折行的 base64 很常见,这不算脏数据。
2 MB 上限的依据:解码结果 2097152 字节对应 base64 长 2796204 字符。这是交互体验阈值不是能力上限——V8 的字符串上限远高于此,但 atob 是同步操作,兆级输入会冻结页面主线程。更大的图片请走「图片压缩」类工具先缩小再编码。
内存释放:每个 Blob URL 都占用解码后的完整字节,图片反复解码会累积。本页在覆盖预览前 revoke 上一个 URL;如果你在自己的代码里做同样的事,记得 blob: 链接不会因为 img 被移除而自动释放。
常见问题
为什么我声明的 image/png,本页却说它是 JPEG?
因为类型判定看字节不看声明。Data URL 的 MIME 部分是写入时的标注,复制粘贴、接口转手时经常被默认值污染。PNG 签名是 89 50 4E 47 开头,JPEG 是 FF D8 FF 开头,两者不可能混淆。本页以嗅探为准并报错提醒,图片该存成什么扩展名也以嗅探结果为准。
atob 直接返回的不就是字节数组吗?为什么还要转 Uint8Array?
atob 返回的是 JavaScript 字符串,每个字符的码位恰好 0-255,看起来像字节但类型是 string。Blob 构造函数收到字符串时会按 UTF-8 重新编码,码位大于 127 的字符会被拆成多字节,图片数据就此损坏。必须用 Uint8Array.from(bin, c => c.charCodeAt(0)) 把码位原样转成字节。这是 base64 解码最常见的踩坑点,没有之一。
base64 为什么会让图片变大三分之一?有没有办法避免?
base64 把每 3 字节(24 位)重排成 4 个字符(也是 24 位信息),但字符在存储里各占 1 字节,所以 3 字节变 4 字节,恒定 +33.33%。这是编码机制的数学下限,任何工具都绕不开。避免办法是别内嵌:把图片当独立文件传输。小图标内嵌省一次请求、大图内嵌纯亏,分界线通常在几 KB。
解码成功但图片显示不出来,是什么问题?
先看嗅探结果:如果是 TIFF、HEIC 这类浏览器不渲染的格式,字节是好的、<img> 不认,下载后用本地看图软件能打开。如果嗅探也不认识,前 4 字节不在魔数表里,多半是损坏或被二次编码过的数据。另外 SVG 是文本格式没有魔术字节,本页按设计不处理它。
带换行的 base64(邮件里那种每 76 字符一折)能直接解吗?
能。本页在解码前剥除所有空白字符,RFC 4648 本身也要求解码器容忍换行。剥除后重新校验长度是否为 4 的倍数与字符集合法性,所以折行不会导致误判——但折行处如果被邮件客户端插入了别的文字,第一个非法字符的报错会精确指出位置。
URL-safe base64 的 - 和 _ 为什么不直接兼容?
因为两种字母表的混用是错误信号。标准 base64 里的 + / 在 URL 里有特殊含义,所以出现了替换版;一段数据用了哪种字母表取决于编码方。如果解码器静默兼容,被 URL 传输污染过的串(+ 变空格等)会被错误地「修复」,你拿到的是一张坏图还以为没问题。本页选择报错并告诉你替换规则,30 秒就能手动修好。
解码后怎么知道图片的宽高?要真的显示出来才能知道吗?
PNG 不需要。IHDR 块固定紧跟在 8 字节签名后,宽是第 16-19 字节、高是 20-23 字节,按大端序读。示例在第 16-19 字节读到 0,0,0,10 即 10。JPEG 的宽高藏在 SOF0 帧里,要按 0xFF 0xC0 标记扫段,逻辑复杂一些,本页对 JPEG 直接用浏览器解码后的自然尺寸显示。
这个工具和站内的图片转 Base64、Base64URL 编码解码是什么关系?
三个页面方向和对象都不同。本页是「二进制图片 ← base64 字符串」的还原与嗅探,Base64转图片转换器的核心价值就在「按字节判定」这四个字上;图片转Base64转换器是反向,从本地图片文件生成 Data URL;Base64URL编码解码处理的是文本而非二进制,字母表也不同。要还原图片回本页,要生成 Data URL 去图片转 Base64 那页。
相关工具
- 图片转Base64转换器:本页的逆操作,从图片文件生成 Data URL。
- Base64URL编码解码:文本与 URL-safe base64 的互转,字母表差异在这页讲。
- 图片尺寸查询:拿到文件后查宽高、格式与体积的专项页。
- 缩略图生成:图片太大超 2 MB 上限时,先缩再转 base64。
- PNG转ICO转换器:嗅探出 PNG 后要做成站点图标走这条。
- WebP转PNG转换器:WebP 在老环境里兼容性差,转 PNG 再分发。
- favicon生成器:图标从生成到内嵌进 Data URL 的一条龙入口。