使用 Node.js 进行图像压缩
目前,我感觉市场越来越倾向于使用第三方服务来构成我们流程的一部分。最常见的服务之一就是压缩图像。
但是,我将展示,使用一个简单的Express.js API,我们可以上传图像、更改 Mime 类型并减小其大小。
我觉得我不需要讨论 Express.js,因为每个使用 Node.js 的人都用过这个框架。今天我主要讲一下multer和sharp。
如今,上传图片是所有应用程序最基本的操作之一。Multer 是一个处理 multipart/form-data 的中间件,主要用于文件上传。将 Express.js 与 multer 结合使用,我们可以轻松实现文件上传功能。
Sharp 是 Node.js 的一个模块,用于将各种格式和各种尺寸的图像转换为较小的尺寸,而不必担心颜色空间、通道和 alpha 透明度,因为所有这些都得到了正确处理。
本例中使用的图像格式是WebP,它的压缩率比 png 和 jpg 更高,有助于更快地加载网页。而且所有浏览器都支持 WebP 。
如何使用
首先,我们将在 Node.js 中创建一个新项目,然后安装必要的依赖项:
# We will use the default values.
npm init -y
# Necessary dependencies.
npm install express multer sharp
之后我们将创建一个简单的api:
const express = require("express");
const app = express();
app.get("/", (req, res) => {
return res.json({ message: "Hello world 🔥🇵🇹" });
});
app.listen(3000);
一旦应用程序正常运行,我们将继续配置 multer。如果您查看过 multer 文档,我相信您已经看到我们可以通过两种方式保存图像:DiskStorage 或 MemoryStorage。
在本例中,我们将使用 MemoryStorage,因为我们希望访问 multer 提供的缓冲区。此外,我们还将使用 Express.js 的静态函数,以便稍后提供图像。
const express = require("express");
const multer = require("multer");
const app = express();
const storage = multer.memoryStorage();
const upload = multer({ storage });
app.use(express.static("./uploads"));
app.get("/", (req, res) => {
return res.json({ message: "Hello world 🔥🇵🇹" });
});
app.listen(3000);
之后,我们将创建一个端点以使用 POST 动词发出 http 请求,但是我们将添加中间件上传,并且我们将只上传一个我们称之为“图片”的文件。
app.post("/", upload.single("picture"), async (req, res) => {
// The logic goes here.
});
下一步是检查工作区中是否存在“uploads”文件夹。如果不存在,我们需要 Node.js 为我们创建它。为此,我们需要访问文件系统,因此我们将使用fs模块。
app.post("/", upload.single("picture"), async (req, res) => {
fs.access("./uploads", (error) => {
if (error) {
fs.mkdirSync("./uploads");
}
});
// Even more logic goes here.
});
现在我们可以开始使用 sharp 了,但首先我想创建一个随机字符串,放在图像名称之前,因为多张图片可能同名,所以最好谨慎处理。在本例中,我使用了时间戳(为了更容易理解),但理想情况下,应该使用一个 16 个字符的随机字符串。然后,我们将通过 multer 访问缓冲区和图像的原始名称。
app.post("/", upload.single("picture"), async (req, res) => {
fs.access("./uploads", (error) => {
if (error) {
fs.mkdirSync("./uploads");
}
});
const { buffer, originalname } = req.file;
const timestamp = new Date().toISOString();
const ref = `${timestamp}-${originalname}.webp`;
// Even more logic goes here.
});
现在只需将图像缓冲区传递给 sharp,然后配置所需的质量、所需的格式以及文件的存储位置。在本例中,我希望将文件存储在“uploads”文件夹中,并使用我们指定的名称(ref变量)。
app.post("/", upload.single("picture"), async (req, res) => {
fs.access("./uploads", (error) => {
if (error) {
fs.mkdirSync("./uploads");
}
});
const { buffer, originalname } = req.file;
const timestamp = new Date().toISOString();
const ref = `${timestamp}-${originalname}.webp`;
await sharp(buffer)
.webp({ quality: 20 })
.toFile("./uploads/" + ref);
// Almost finished...
});
最后但同样重要的一点是,我将创建一个名为link的变量,它将成为我们在浏览器中查看新图像的 url。
最终代码应该如下:
const express = require("express");
const multer = require("multer");
const sharp = require("sharp");
const fs = require("fs");
const app = express();
const storage = multer.memoryStorage();
const upload = multer({ storage });
app.use(express.static("./uploads"));
app.get("/", (req, res) => {
return res.json({ message: "Hello world 🔥🇵🇹" });
});
app.post("/", upload.single("picture"), async (req, res) => {
fs.access("./uploads", (error) => {
if (error) {
fs.mkdirSync("./uploads");
}
});
const { buffer, originalname } = req.file;
const timestamp = new Date().toISOString();
const ref = `${timestamp}-${originalname}.webp`;
await sharp(buffer)
.webp({ quality: 20 })
.toFile("./uploads/" + ref);
const link = `http://localhost:3000/${ref}`;
return res.json({ link });
});
app.listen(3000);
只需使用您最喜欢的 http 客户端(在本例中我使用了Insomnia),并且不要忘记使用 multipart/form-data 发送图像,并且字段的名称必须是“图片”,类型是文件。
像这样:
你呢?
您最喜欢的图像格式是什么?
文章来源:https://dev.to/franciscomendes10866/image-compression-with-node-js-4d7h