我有一个Web应用程序,它接收用户上传的图像,上传到S3(通过multer-s3)并获取URL,通过名为" sharp"的模块从中收集一些元数据。 (即维度,mime类型等等),然后将此信息写入db。
这些是非常高分辨率的照片(从2到19 mb开始)并且我不确定处理它们的最佳方式是什么。我应该在第一次获取文件时将它们写入文件,然后从那里流式传输,或者我应该继续将其保存在内存中直到我完成。
上传后的部分,我通过锐利运行图像,是最让我担心的部分。因为sharp不能使用流,所以我将流转换为缓冲区:
async getImageDimensions(fileStream){
let buffer = await this._streamToBuffer(fileStream);
let metadata = await sharp(buffer).metadata();
return {width: metadata.width, height: metadata.height};
}
_streamToBuffer(stream){
return new Promise((resolve, reject) => {
let buffers = [];
stream.on('error', reject);
stream.on('data', (data) => buffers.push(data));
stream.on('end', () => resolve(Buffer.concat(buffers)));
});
}
上述代码段与其他两个异步函数同时运行,并将结果插入到db中。我做错了吗?写入本地文件并指向该文件更好吗?
感谢您的建议
答案 0 :(得分:1)
sharp
支持基于Promise的(即异步/等待)输出的基于流的输入。
以下是您的示例的修改版本,以演示如何实现此目标。
async getImageDimensions(fileStream){
const writableStream = sharp();
fileStream.pipe(writableStream);
const metadata = await writableStream.metadata();
return {width: metadata.width, height: metadata.height};
}
就方法而言,metadata()
不会解码任何像素数据,通常是任何图像文件的大部分,因此您可以尝试在尺寸接近开始时截断fileStream
。