使用NodeJS调用OpenAI生成图片变体时出现400错误
解决OpenAI Image Variation API报错:"Uploaded image must be a PNG and less than 4 MB"
以下是针对你的情况的排查和修复方案:
1. 确保异步保存图片完成后再调用API
你的saveToDir函数使用了fs.writeFile的回调版本,但未正确等待文件写入完成。如果在文件还未完全写入时就调用GPTImageVariations,读取到的会是不完整的损坏文件,直接导致API报错。
修复saveToDir,改用Promise版本的fs.writeFile并通过await等待完成:
const saveToDir = async (bufferString) => { const bufferImage = Buffer.from(bufferString, "base64"); try { await fs.promises.writeFile("sampleImage.png", bufferImage); console.log("Image saved successfully"); } catch (err) { console.log("Error saving image: ", err); throw err; // 抛出错误让调用方感知并处理 } };
调用时需确保等待保存完成后再执行变体生成:
// 示例调用流程 async function processUserImage(bufferString) { await saveToDir(bufferString); await GPTImageVariations(); }
2. 清理base64字符串的前缀
如果用户发送的图片base64带有data:image/png;base64,这类前缀,直接用Buffer.from解析会导致生成的文件损坏。需先去除前缀:
修改saveToDir中的buffer处理逻辑:
const saveToDir = async (bufferString) => { // 移除base64前缀(如果存在) const cleanBase64 = bufferString.replace(/^data:image\/png;base64,/, ""); const bufferImage = Buffer.from(cleanBase64, "base64"); // 后续保存代码不变 };
3. 验证保存后的图片有效性
PNG文件的前8字节固定为89 50 4E 47 0D 0A 1A 0A,可以通过验证文件头确认保存的是有效PNG:
const isValidPng = async (filePath) => { const headerBuffer = await fs.promises.readFile(filePath, { length: 8 }); const standardPngHeader = Buffer.from([0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A]); return headerBuffer.equals(standardPngHeader); };
在调用API前先执行验证:
const GPTImageVariations = async () => { try { const valid = await isValidPng("sampleImage.png"); if (!valid) { throw new Error("Saved file is not a valid PNG"); } const response = await openai.createImageVariation( fs.createReadStream("sampleImage.png"), 1, "512x512" ); console.log(response.data.data[0].url); } catch (error) { // 原有错误处理逻辑不变 } };
4. 显式指定读取流为二进制模式
虽然fs.createReadStream默认是二进制模式,但显式指定编码为null可以避免潜在的编码问题:
fs.createReadStream("sampleImage.png", { encoding: null })
以上方案覆盖了核心问题点:确保图片完整写入、base64数据格式正确、文件为有效PNG格式,应该能解决你遇到的报错。
内容的提问来源于stack exchange,提问作者SAK
相关产品推荐
相关产品推荐

