如何将 Base64 转换为 PNG
- 把 Base64 或完整的
data:image/png;base64,...URI 粘贴到输入框。也可以打开或拖入存有该字符串的.txt文件。 - 查看状态行:应显示 有效的 Base64,检测结果 为 PNG。预览会显示图片及其像素尺寸。
- 需要的话修改 文件名。扩展名 已经是
png。 - 点击 下载文件。
如果数据原来是另一种格式,预览上方会出现提示,例如“这看起来是 JPEG,而不是 PNG”,并附带 下载为 .jpg 按钮。改名不会转换任何东西,所以通常按真实扩展名保存更好。
PNG 的 Base64 从哪里来
很多以文本形式交付图片的工具,默认输出都是 PNG:
- 浏览器中的
canvas.toDataURL()会返回 PNG 的 data URI,除非你指定其他类型。签名板、绘图应用和导出图片的图表库都基于它。 - 浏览器自动化:Selenium 的
get_screenshot_as_base64()和 Puppeteer 的page.screenshot({ encoding: "base64" })以不带前缀的纯 Base64 返回 PNG 截图。测试报告经常把它们嵌入 JSON 或 HTML。 - 生成二维码、条形码、验证码、地图和图像的 API 通常在 JSON 字段中返回 PNG。
- 内联图标的 HTML 和 CSS,以及报告和 notebook 的单文件导出。
这些都可以直接粘贴。换行、末尾缺少的 = 以及 URL 安全字符都能容忍;补上填充时,状态行会注明。
读懂 PNG 文件头
PNG 以 8 字节的签名开头,紧接着是保存图片基本属性的 IHDR 块。点击 显示 hex 转储 即可查看。对于一张 120×40 的透明图片,前两行是:
00000000 89 50 4e 47 0d 0a 1a 0a 00 00 00 0d 49 48 44 52 |.PNG........IHDR|
00000010 00 00 00 78 00 00 00 28 08 06 00 00 00 35 ea 3e |...x...(.....5.>|
| 偏移 | 字节 | 含义 |
|---|---|---|
0x00 | 89 50 4e 47 0d 0a 1a 0a | PNG 签名,Base64 中为 iVBORw0KGgo |
0x10 | 00 00 00 78 | 宽度:0x78 = 120 px |
0x14 | 00 00 00 28 | 高度:0x28 = 40 px |
0x18 | 08 | 位深度:每通道 8 位 |
0x19 | 06 | 颜色类型:6 = RGBA |
颜色类型告诉你这是哪一种 PNG:00 灰度、02 RGB、03 调色板(索引色)、04 带 alpha 的灰度、06 带 alpha 的 RGB。经过优化工具处理的调色板 PNG 往往比 RGBA 的小得多,当 Base64 需要尽量短时,这一点很有用。
如果尺寸看起来很离谱,比如宽度达到几百万像素,说明签名之后的字节已经损坏,预览会失败。
在代码中检查 PNG
不借助任何图像库,用几行 Python 就能读出同样的文件头字段。按逗号拆分,使它对纯 Base64 和 data URI 都适用:
import base64, struct
def png_info(b64: str) -> dict:
data = base64.b64decode(b64.split(",", 1)[-1])
if data[:8] != b"\x89PNG\r\n\x1a\n":
raise ValueError("not a PNG")
width, height, depth, color_type = struct.unpack(">IIBB", data[16:26])
return {"width": width, "height": height, "bit_depth": depth, "color_type": color_type}
在 Node.js 中写文件,fs.writeFileSync("shot.png", Buffer.from(b64, "base64")) 就够了。Node 的 Base64 解码器会跳过换行,也接受 URL 安全字符。更多内容见 Python 中的 Base64 和 Node.js 中的 Base64。
PNG 无法解码或显示时
- “无效字符”错误。 字符串中混入了 Base64 以外的内容:
\/这样的 JSON 转义、HTML 实体,或者日志行的其余部分。错误信息会给出位置,修复 Base64 可以清理这些常见问题。 - 图片只画出一部分或者缺失。 字符串被截断了。完整的 PNG 以
IEND块结尾;如果你知道原始文件的大小,请与 大小 对比。 - “这看起来不像 PNG”。 字节根本不是以 PNG 签名开头。这通常是加密数据、hex 之类的其他编码,或者被编码了两次的 Base64,后一种情况会出现 再次解码。
- 预览正常,但另一个程序拒绝这个文件。 把这里显示的 SHA-256 与该程序收到的文件的哈希对比。如果一致,说明解码出的文件没问题,问题出在那个程序。
反方向编码 PNG,请使用 PNG 转 Base64。
常见问题
怎么把 canvas toDataURL() 的结果保存为 PNG 文件?
复制 canvas.toDataURL() 返回的整个字符串,粘贴到上方,点击 下载文件。前缀会自动处理,文件以 .png 保存,因为这是 toDataURL() 的默认格式。
我的 Base64 不是以 iVBORw0KGgo 开头,它还是 PNG 吗?
不是。无论大小,每个 PNG 都以这几个字符开头。如果页面报告的是 JPEG、WebP 或其他格式,说明数据从来就不是 PNG,保存为 .png 只是改了名字。请用 下载为 保留真实类型。
怎么知道 PNG 的背景是否透明?
打开 显示 hex 转储,读取偏移 0x19 处的字节,即颜色类型。06(RGBA)和 04(带 alpha 的灰度)带有 alpha 通道。类型 02、03 和 00 仍可以通过 tRNS 块实现透明。
APNG 动图会保留动画吗?
会。APNG 是带有额外帧块的 PNG,解码会保留每一个字节。在支持 APNG 的浏览器中预览会播放动画,当前所有浏览器都支持。