如何将Azure计算机视觉API返回的ReadableStream图像写入文件?
解决Azure Computer Vision API缩略图ReadableStream写入文件的问题
你的核心问题在于只读取了ReadableStream的第一个Buffer块,图片数据通常会被拆分成多个chunk传输,只写入第一个chunk的话,文件是不完整的,自然无法被识别。下面给你两种可行的解决方案:
方法一:用Stream.pipe直接写入(推荐)
这是Node.js处理流数据的标准方式,pipe会自动帮你处理所有数据块的传输、背压和流结束逻辑,简单高效:
const fs = require('fs'); const { ComputerVisionClient } = require('@azure/cognitiveservices-computervision'); const { DefaultAzureCredential } = require('@azure/identity'); // 初始化客户端(请替换为你的API端点和凭证配置) const computerVisionClient = new ComputerVisionClient( new DefaultAzureCredential(), 'https://<你的区域>.cognitiveservices.azure.com/' ); async function saveThumbnail() { const dogURL = 'https://moderatorsampleimages.blob.core.windows.net/samples/sample16.png'; const thumbResponse = await computerVisionClient.generateThumbnail(100, 100, dogURL, { smartCropping: true }); // 创建写入流,将可读流直接pipe进去 const writeStream = fs.createWriteStream('thumb.jpg'); thumbResponse.readableStreamBody.pipe(writeStream); // 监听流完成和错误事件 writeStream.on('finish', () => { console.log('缩略图已成功保存!'); }); writeStream.on('error', (err) => { console.error('保存缩略图时出错:', err); }); } // 执行函数并捕获错误 saveThumbnail().catch(err => console.error('整体流程出错:', err));
方法二:手动收集所有Chunk后写入
如果你需要先对图片数据做一些处理再写入,可以手动收集所有Buffer块,合并后再写入文件:
const fs = require('fs').promises; // 使用promise版的fs API,更贴合async/await风格 const { ComputerVisionClient } = require('@azure/cognitiveservices-computervision'); const { DefaultAzureCredential } = require('@azure/identity'); async function saveThumbnail() { const dogURL = 'https://moderatorsampleimages.blob.core.windows.net/samples/sample16.png'; const thumbResponse = await computerVisionClient.generateThumbnail(100, 100, dogURL, { smartCropping: true }); // 收集所有数据块 const chunks = []; for await (const chunk of thumbResponse.readableStreamBody) { chunks.push(chunk); } // 合并所有chunk为一个完整的Buffer const fullImageBuffer = Buffer.concat(chunks); // 写入文件 await fs.writeFile('thumb.jpg', fullImageBuffer); console.log('缩略图已成功保存!'); } saveThumbnail().catch(err => console.error(err));
为什么你的原代码不行?
你访问的readableBuffer.head.data是ReadableStream内部链表结构的第一个节点数据,后面还有next节点存储剩余的图片数据。只取head.data相当于只写入了图片的一小部分,文件不完整,所以系统无法识别它的类型。
内容的提问来源于stack exchange,提问作者Azurespot
相关产品推荐
相关产品推荐

