解析Base64编码数组为几何数据时遇到问题
问题:解析glTF Base64几何数据时字节数不符、数值错误
问题分析
你的核心错误在于使用atob(str)后直接传入Blob构造函数。atob返回的是UTF-16编码的字符串,当把它作为Blob内容时,浏览器会自动将其转换为UTF-8编码,这会破坏原始二进制数据——比如某些字节值在UTF-8中属于无效序列,会被替换成替代字符,或是多字节编码导致字节数膨胀,最终导致解析出的ArrayBuffer长度和内容完全错误。
正确的解析方法
不需要使用Blob和异步操作,直接将Base64解码后的字符串转换为Uint8Array即可,步骤简单直接:
- 用
atob解码Base64字符串,得到原始二进制字符串 - 遍历字符串的每个字符,将其ASCII码值存入Uint8Array
- 从Uint8Array获取对应的ArrayBuffer,用于后续创建类型数组
对应代码实现:
function ingest_base64(str) { // 解码Base64字符串 const binaryStr = atob(str); // 创建对应长度的Uint8Array const uint8 = new Uint8Array(binaryStr.length); // 逐个字符转换为字节 for (let i = 0; i < binaryStr.length; i++) { uint8[i] = binaryStr.charCodeAt(i); } // 返回原始二进制缓冲区 return uint8.buffer; }
测试验证
用你的测试Base64字符串调用该函数,得到的结果将完全符合教程要求:
const buffer = ingest_base64('AAABAAIAAAAAAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAA='); console.log(buffer.byteLength); // 输出44,和教程一致 // 验证顶点索引数据(前6字节,无符号短整型) const indices = new Uint16Array(buffer, 0, 3); console.log(indices); // 输出 [0, 1, 2] // 验证位置数据(从第8字节开始,共9个浮点数) const positions = new Float32Array(buffer, 8, 9); console.log(positions); // 输出 [0,0,0, 1,0,0, 0,1,0]
额外优化:处理完整Data URL
如果需要直接解析带前缀的Data URL,可以先拆分出Base64部分再解码:
function parse_data_url(dataUrl) { const [prefix, base64Str] = dataUrl.split(','); if (!prefix.includes('base64')) { throw new Error('仅支持Base64编码的Data URL'); } return ingest_base64(base64Str); }
内容的提问来源于stack exchange,提问作者user2628206
相关产品推荐
相关产品推荐

