如何在使用 gridfs 保存之前调整大小和图像?
Posted
技术标签:
【中文标题】如何在使用 gridfs 保存之前调整大小和图像?【英文标题】:How to resize and image before saving it with gridfs? 【发布时间】:2020-02-16 11:38:25 【问题描述】:我是 mongoDB 和 gridfs 的初学者。我有一个在数据库中保存传入图像的代码。但我想在保存之前调整图像大小。它尝试使用sharp,但我不太明白它是如何工作的。
我尝试了以下代码,但它不起作用
const storage = new GridFsStorage(
url: mongoURI,
file: (req, file) =>
return new Promise((resolve, reject) =>
const filename = req.params.userID;
const fileInfo =
filename: filename,
bucketName: "ProfilePic",
;
resolve(fileInfo);
);
);
const upload = multer( storage );
router.post("/setProfilePic/:userID", upload.single("picture"), async(req, res) =>
//code not working
await sharp(req.file.path)
.resize(500)
.jpeg(quality: 50)
.toFile(
path.resolve(req.file.destination,'resized',image)
)
// end of non working code
return res.status(200).json(state: "ok")
);
【问题讨论】:
sharp 可能会抛出错误。你能用try..catch
块包围await
并记录错误吗?
【参考方案1】:
我的解决方案是使用'multer-gridfs-storage'
中的fromStream
方法
这个想法是这样的:
-
使用
multer
解析文件,获取文件缓冲区(原始数据)
使用sharp
捕获输入缓冲区并创建另一个包含调整大小的图像的缓冲区。
使用Readable
创建可读流,然后应用fromStream
方法将流通过管道传输到数据库。
实施
const multer = require('multer')
const GridFsStorage = require("multer-gridfs-storage");
const Readable = require("stream"); // from nodejs
const sharp = require("sharp");
const storage = new GridFsStorage(
url: mongoURI,
options: useUnifiedTopology: true , // silence the warning
file: () => ( bucketName: "ProfilePic",filename: req.params.userID ),
);
router.post("/setProfilePic/:userID",multer().single('picture'),(req,res) =>
const file = req.file
const buffer = file.buffer
// chain sharp methods
sharp(buffer)
.resize(500)
.jpeg( quality: 50 )
.toBuffer((err, data, info) =>
// data here directly contains the buffer object.
const fileStream = Readable.from(data);
// write the resized stream to the database.
storage.fromStream(fileStream, req, file).then(() =>
res.json( state: 'ok' );
);
);
)
我没有充分利用 multer 的存储引擎,而是创建了自己的流。
我也是 MongoDB 初学者,所以我很高兴能够让它工作。如果还是不行,请留言,我会尽力解决的。
【讨论】:
【参考方案2】:我使用了上一个答案。我进行了一些更改以使其正常工作。我的 req.file.buffer 始终未定义。所以我做了一些改动。
我想在下面强调两件事
确保使用 multer 版本“^2.0.0-rc.1”。
您可以通过以下方式创建缓冲区
const buffer = await getStream.buffer(req.file.stream);
解决方案的其余部分完全相同。这是完整的代码示例。
const multer = require('multer')
const GridFsStorage = require("multer-gridfs-storage");
const Readable = require("stream"); // from nodejs
const sharp = require("sharp");
const getStream = require("get-stream");
const storage = new GridFsStorage(
url: mongoURI,
options: useUnifiedTopology: true , // silence the warning
file: () => ( bucketName: "ProfilePic",filename: req.params.userID ),
);
app.post("/setProfilePic/:userID", multer.single("image"), async (req, res) =>
const file = req.file;
const buffer = await getStream.buffer(req.file.stream);
// chain sharp methods
sharp(buffer)
.resize(200, 100)
.jpeg( quality: 50 )
.toBuffer((err, data, info) =>
// data here directly contains the buffer object.
const fileStream = Readable.from(data);
// write the resized stream to the database.
storage.fromStream(fileStream, req, file).then(() =>
res.json( state: "ok" );
);
);
);
【讨论】:
以上是关于如何在使用 gridfs 保存之前调整大小和图像?的主要内容,如果未能解决你的问题,请参考以下文章