如何用FileSystemFileHandle接口从Base64字符串创建写入图片文件
问题描述
我有一个带data:image/jpg;base64,前缀的Base64字符串,尝试用JavaScript的FileSystemFileHandle接口创建图片文件。文件名取自页面文本框输入的字符串,getNewFileHandle函数能成功创建文件句柄,但写入文件后Windows提示文件格式不支持。通过超链接可以正常下载图片,但需求必须使用保存文件选择器实现。
保存文件代码
async function saveNewFile(name, content) { let fileHandle = await getNewFileHandle(name); const file = await fileHandle.createWritable(); await file.write(content); await file.close(); return; }
获取文件句柄代码
//Creates Save File Window, creates writable file. Called from saveNewFile async function getNewFileHandle(name) { const opts = { suggestedName: name, types: [{ description: 'Image file', accept: {'application/octet-stream': ['.jpg']}, }], }; return await window.showSaveFilePicker(opts); }
解决方法
FileSystemFileHandle完全支持写入图片,问题出在你直接写入了带前缀的Base64字符串——这是文本格式,并非图片的二进制原始数据,导致系统无法识别。
按以下步骤修改代码即可解决:
- 剥离Base64前缀:移除
data:image/jpg;base64,部分,只保留纯Base64编码内容。 - 转换为二进制数据:用
atob()解码Base64字符串为二进制字符串,再转换为Uint8Array类型的二进制数组。 - 写入二进制数据:将转换后的二进制数组写入文件句柄。
修改后的saveNewFile函数:
async function saveNewFile(name, content) { let fileHandle = await getNewFileHandle(name); // 剥离Base64前缀 const base64Data = content.replace(/^data:image\/jpg;base64,/, ''); // 解码为二进制数据 const binaryStr = atob(base64Data); const uint8Array = new Uint8Array(binaryStr.length); for (let i = 0; i < binaryStr.length; i++) { uint8Array[i] = binaryStr.charCodeAt(i); } // 写入二进制数据 const file = await fileHandle.createWritable(); await file.write(uint8Array); await file.close(); }
另外,建议优化getNewFileHandle中的accept配置,使用标准的图片MIME类型,避免潜在的类型识别问题:
types: [{ description: 'JPEG Image', accept: {'image/jpeg': ['.jpg', '.jpeg']}, }]
内容的提问来源于stack exchange,提问作者bwalt060
相关产品推荐
相关产品推荐

