主题
文件上传与图片处理
在本章节中,我们将介绍如何在 Express 应用中实现文件上传和图片处理功能。我们将使用 Multer 中间件来处理上传的文件,并使用 Sharp 库对图片进行基本的处理操作,如缩放、裁剪和格式转换。通过这个例子,您将学会如何处理用户上传的文件,并对图片进行简单的操作。
1. 安装依赖
首先,您需要安装 Multer 和 Sharp 库:
bash
npm install multer sharp
- Multer:用于处理
multipart/form-data
类型的表单数据,特别是文件上传。 - Sharp:用于处理和转换图片,如缩放、裁剪、格式转换等。
2. 设置 Multer 中间件
Multer 中间件用于处理文件上传。我们将配置 Multer 来存储文件,并设置上传文件的大小限制。
2.1 配置文件存储
首先,我们需要创建一个存储配置,指定上传的文件存储位置和文件名。
js
const multer = require('multer');
const path = require('path');
// 设置存储引擎
const storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, 'uploads/'); // 文件存储的目录
},
filename: (req, file, cb) => {
cb(null, Date.now() + path.extname(file.originalname)); // 文件名使用时间戳,避免重复
}
});
// 创建 Multer 实例
const upload = multer({
storage: storage,
limits: { fileSize: 10 * 1024 * 1024 }, // 限制文件大小为 10MB
});
module.exports = upload;
2.2 创建上传路由
接下来,我们在 Express 中创建一个路由,用于接收文件上传。
js
const express = require('express');
const upload = require('../middlewares/upload');
const path = require('path');
const router = express.Router();
// 上传单个文件
router.post('/upload', upload.single('image'), (req, res) => {
if (!req.file) {
return res.status(400).json({ message: 'No file uploaded' });
}
res.status(200).json({
message: 'File uploaded successfully',
file: req.file,
filePath: `/uploads/${req.file.filename}`, // 返回文件的相对路径
});
});
module.exports = router;
这里,我们使用了 upload.single('image')
来处理上传单个文件的请求。'image'
是表单中上传文件的字段名。
3. 图片处理
我们将使用 Sharp 来处理上传的图片,支持操作如缩放、裁剪和格式转换。
3.1 图片缩放
假设我们需要上传的图片在服务器中保存为原始尺寸,但我们也希望生成一张缩小版的图片,用于预览。
js
const sharp = require('sharp');
const path = require('path');
const fs = require('fs');
// 处理图片,生成缩小版图片
router.post('/upload', upload.single('image'), async (req, res) => {
if (!req.file) {
return res.status(400).json({ message: 'No file uploaded' });
}
const { filename, path: filePath } = req.file;
// 生成缩小版图片
const thumbnailPath = path.join('uploads', 'thumbnails', `thumb_${filename}`);
try {
await sharp(filePath)
.resize(150, 150) // 设置宽高为 150x150
.toFile(thumbnailPath);
res.status(200).json({
message: 'File uploaded and thumbnail generated',
file: req.file,
filePath: `/uploads/${filename}`,
thumbnailPath: `/uploads/thumbnails/thumb_${filename}`,
});
} catch (err) {
res.status(500).json({ message: 'Error processing image', error: err });
}
});
3.2 图片裁剪
如果我们需要用户上传的图片裁剪为指定尺寸,可以使用 Sharp 来裁剪图片。
js
router.post('/upload', upload.single('image'), async (req, res) => {
if (!req.file) {
return res.status(400).json({ message: 'No file uploaded' });
}
const { filename, path: filePath } = req.file;
// 设置裁剪区域
const cropWidth = 200;
const cropHeight = 200;
const croppedImagePath = path.join('uploads', 'cropped', `crop_${filename}`);
try {
await sharp(filePath)
.extract({ width: cropWidth, height: cropHeight, left: 0, top: 0 }) // 从图片左上角开始裁剪
.toFile(croppedImagePath);
res.status(200).json({
message: 'File uploaded and image cropped',
file: req.file,
filePath: `/uploads/${filename}`,
croppedImagePath: `/uploads/cropped/crop_${filename}`,
});
} catch (err) {
res.status(500).json({ message: 'Error cropping image', error: err });
}
});
3.3 图片格式转换
除了缩放和裁剪,Sharp 还支持将图片转换为其他格式,如将上传的 JPG 图片转换为 PNG 格式。
js
router.post('/upload', upload.single('image'), async (req, res) => {
if (!req.file) {
return res.status(400).json({ message: 'No file uploaded' });
}
const { filename, path: filePath } = req.file;
const convertedImagePath = path.join('uploads', 'converted', `${path.parse(filename).name}.png`);
try {
await sharp(filePath)
.toFormat('png') // 转换为 PNG 格式
.toFile(convertedImagePath);
res.status(200).json({
message: 'File uploaded and image converted',
file: req.file,
filePath: `/uploads/${filename}`,
convertedImagePath: `/uploads/converted/${path.parse(filename).name}.png`,
});
} catch (err) {
res.status(500).json({ message: 'Error converting image', error: err });
}
});
4. 图片压缩
如果文件上传后过大,我们也可以使用 Sharp 来压缩图片。
js
router.post('/upload', upload.single('image'), async (req, res) => {
if (!req.file) {
return res.status(400).json({ message: 'No file uploaded' });
}
const { filename, path: filePath } = req.file;
const compressedImagePath = path.join('uploads', 'compressed', `compressed_${filename}`);
try {
await sharp(filePath)
.jpeg({ quality: 70 }) // 压缩成质量为 70 的 JPEG 格式
.toFile(compressedImagePath);
res.status(200).json({
message: 'File uploaded and image compressed',
file: req.file,
filePath: `/uploads/${filename}`,
compressedImagePath: `/uploads/compressed/compressed_${filename}`,
});
} catch (err) {
res.status(500).json({ message: 'Error compressing image', error: err });
}
});
5. 总结
在本章节中,您学会了如何使用 Multer 来处理 Express 中的文件上传,并结合 Sharp 实现了基本的图片处理功能,包括缩放、裁剪、格式转换和压缩。您可以根据实际需求,扩展更多功能,例如设置上传文件的类型限制、对多个文件的处理等。
通过这些操作,您可以为 Express 应用添加强大的文件上传和处理功能,支持用户上传图片并对其进行各种操作。