feat:增加更改图片大小功能
This commit is contained in:
77
utils.js
Normal file
77
utils.js
Normal file
@@ -0,0 +1,77 @@
|
||||
const path = require('path');
|
||||
const sharp = require('sharp');
|
||||
|
||||
// 压缩配置
|
||||
const compressOptions = {
|
||||
quality: 0.7,
|
||||
maxHeight: 800,
|
||||
maxWidth: 600
|
||||
};
|
||||
|
||||
/**
|
||||
* 安全检查:防止路径遍历攻击(如 ../../etc/passwd)
|
||||
* @param {string} targetPath 目标文件路径
|
||||
* @param {string} baseDir 基础目录
|
||||
* @returns {boolean} 是否合法
|
||||
*/
|
||||
function isSafePath(targetPath, baseDir) {
|
||||
const resolvedTarget = path.resolve(targetPath).toLowerCase();
|
||||
const resolvedBase = path.resolve(baseDir).toLowerCase();
|
||||
return resolvedTarget.startsWith(resolvedBase);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送响应
|
||||
* @param {ServerResponse} res 响应对象
|
||||
* @param {number} statusCode 状态码
|
||||
* @param {string} message 信息
|
||||
*/
|
||||
function sendResponse(res, statusCode, message) {
|
||||
res.writeHead(statusCode, { 'Content-Type': 'text/plain; charset=utf-8' });
|
||||
res.end(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理图片压缩和调整大小
|
||||
* @param {string} imagePath 图片路径
|
||||
* @param {Object} query 查询参数
|
||||
* @returns {Promise<Buffer>} 处理后的图片Buffer
|
||||
*/
|
||||
async function processImage(imagePath, query) {
|
||||
let sharpInstance = sharp(imagePath).rotate();
|
||||
|
||||
// 处理宽高参数
|
||||
let targetWidth = parseInt(query.w) || parseInt(query.width);
|
||||
let targetHeight = parseInt(query.h) || parseInt(query.height);
|
||||
|
||||
// 如果没有指定宽高,使用配置的默认最大宽高
|
||||
if (!targetWidth && !targetHeight) {
|
||||
targetWidth = compressOptions.maxWidth;
|
||||
targetHeight = compressOptions.maxHeight;
|
||||
}
|
||||
|
||||
// 如果指定了宽高,进行调整大小处理
|
||||
if (targetWidth || targetHeight) {
|
||||
const resizeOptions = {
|
||||
width: targetWidth,
|
||||
height: targetHeight,
|
||||
fit: sharp.fit.inside, // 保持宽高比,图片会完整显示在指定区域内
|
||||
withoutEnlargement: true // 不放大比原始尺寸小的图片
|
||||
};
|
||||
sharpInstance = sharpInstance.resize(resizeOptions);
|
||||
}
|
||||
|
||||
// 处理质量参数(优先使用查询参数,否则使用配置的默认值)
|
||||
const quality = query.q ? Math.max(1, Math.min(100, parseInt(query.q))) :
|
||||
Math.round(compressOptions.quality * 100);
|
||||
const finalQuality = Math.max(1, Math.min(100, quality));
|
||||
|
||||
// 转换为JPEG格式并压缩
|
||||
return sharpInstance.jpeg({quality: finalQuality, mozjpeg: true}).toBuffer();
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
isSafePath,
|
||||
sendResponse,
|
||||
processImage
|
||||
}
|
||||
Reference in New Issue
Block a user