获取 Base64 编码数据的 MIME type (文件格式)
缘起
最近在开发关于大模型相关的应用,涉及到文生图的功能。接入大模型的 API 调用后会返回 Base64 编码后的数据,通常情况下返回的图片数据都是 PNG 格式,所以后续默认按照此格式处理即可。但是图片生成后通常需要进行展示,有两种解决方案,第一种返回相关的 Base64 数据让前端渲染,这样需要遵循 Data URI scheme 标准,第二种是上传到对象存储上返回图片的 URL 。 无论那种方案,都需要知道返回数据的 MIME type(通俗理解上的文件格式),虽然可以按照默认值 PNG 进行处理,但是在使用共享的 Base64 文件预览的时候,发现一个 Base64在线预览网站 上能够正确展示编码数据的 MIME type, 我就比较好奇我没有按照 Data URI scheme 标准的数据如何实现的 MIME type 检测的。
解疑
一开始通过搜索相关的信息,然后在著名的编程网站 Stackoverflow 上查询到一段 js 代码 完美的解决了检测 MIME type 的问题。相关代码如下:
var signatures = {
JVBERi0: "application/pdf",
R0lGODdh: "image/gif",
R0lGODlh: "image/gif",
iVBORw0KGgo: "image/png",
"/9j/": "image/jpg"
};
function detectMimeType(b64) {
for (var s in signatures) {
if (b64.indexOf(s) === 0) {
return signatures[s];
}
}
}
// Some tests
console.log(detectMimeType('R0lGODdhAQABAPAAAP8AAAAAACwAAAAAAQABAAACAkQBADs='));
console.log(detectMimeType('iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVR42mP4z8AAAAMBAQD3A0FDAAAAAElFTkSuQmCC'));
console.log(detectMimeType('JVBERi0xLjUKJYCBgoMKMSAwIG9iago8PC9GaWx0ZXIvRmxhdGVEZWNvZGUvRmlyc3QgMTQxL04gMjAvTGVuZ3'));
console.log(detectMimeType('/9j/4AAQSkZJRgABAQAAZABkAAD/2wCEABQQEBkSGScXFycyJh8mMi4mJiYmLj41NTU1NT5EQUFBQUFBRERERERERERE'));
我还想要进一步了解一下代码中通过前缀的字符进行判断的原理,在答案中作者提到了 [Magic Number] (
https://en.wikipedia.org/wiki/File_format#Magic_number
) ,让我联想到文件格式也是通过文件头部的魔法数进行判断的。然后通过
常用文件魔数
这个列表查询到 PNG 文件格式的 Hex 数据为89 50 4E 47 0D 0A 1A 0A
,在通过
Hex TO Base64 编码
得到了 iVBORw0KGgo
这个前缀,与答案中的判断条件一致。至此如何通过 Base64 编码的数据获取 MIME type 的疑问已经被解除,可以拓展一下,如果 Base64 的数据不是图片而是PDF文件类型,也可以通过此魔数的方法进行格式提取。