Files
image-service/utils.js

78 lines
2.4 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
}