104 行
3.2 KiB
JavaScript
104 行
3.2 KiB
JavaScript
// server/utils/imagePreprocessor.js
|
|
import sharp from 'sharp';
|
|
|
|
class ImagePreprocessor {
|
|
constructor() {
|
|
this.tempDir = './temp/processed';
|
|
}
|
|
|
|
async preprocessWithPadding(imagePath, config) {
|
|
try {
|
|
const metadata = await sharp(imagePath).metadata();
|
|
|
|
// 减少填充,避免过度改变图像
|
|
const minPadding = 30;
|
|
const paddingX = Math.max(minPadding, Math.floor(metadata.width * 0.05));
|
|
const paddingY = Math.max(minPadding, Math.floor(metadata.height * 0.05));
|
|
|
|
const paddedWidth = metadata.width + paddingX * 2;
|
|
const paddedHeight = metadata.height + paddingY * 2;
|
|
|
|
const paddedBuffer = await sharp(imagePath)
|
|
.extend({
|
|
top: paddingY,
|
|
bottom: paddingY,
|
|
left: paddingX,
|
|
right: paddingX,
|
|
background: { r: 255, g: 255, b: 255 }
|
|
})
|
|
.png()
|
|
.toBuffer();
|
|
|
|
const { width, height } = this.resizeForDetection({
|
|
width: paddedWidth,
|
|
height: paddedHeight
|
|
}, config);
|
|
|
|
const resizedBuffer = await sharp(paddedBuffer)
|
|
.resize(width, height)
|
|
.png()
|
|
.toBuffer();
|
|
|
|
console.log(`🖼️ 图像预处理完成: ${metadata.width}x${metadata.height} -> ${width}x${height}`);
|
|
|
|
return {
|
|
processedImage: {
|
|
buffer: resizedBuffer,
|
|
width,
|
|
height,
|
|
originalWidth: metadata.width,
|
|
originalHeight: metadata.height,
|
|
paddedWidth: paddedWidth,
|
|
paddedHeight: paddedHeight,
|
|
paddingX,
|
|
paddingY,
|
|
scaleX: paddedWidth / width,
|
|
scaleY: paddedHeight / height
|
|
}
|
|
};
|
|
|
|
} catch (error) {
|
|
console.error('预处理错误:', error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
resizeForDetection(metadata, config) {
|
|
const { width, height } = metadata;
|
|
const limitSideLen = config.detLimitSideLen || 960;
|
|
|
|
let ratio = 1;
|
|
if (Math.max(width, height) > limitSideLen) {
|
|
ratio = limitSideLen / Math.max(width, height);
|
|
}
|
|
|
|
const newWidth = Math.floor(width * ratio);
|
|
const newHeight = Math.floor(height * ratio);
|
|
|
|
return {
|
|
width: Math.max(32, Math.floor(newWidth / 32) * 32),
|
|
height: Math.max(32, Math.floor(newHeight / 32) * 32)
|
|
};
|
|
}
|
|
|
|
async getImageInfo(imagePath) {
|
|
try {
|
|
const metadata = await sharp(imagePath).metadata();
|
|
return {
|
|
width: metadata.width || 0,
|
|
height: metadata.height || 0,
|
|
format: metadata.format || 'unknown',
|
|
processed: false
|
|
};
|
|
} catch (error) {
|
|
return {
|
|
width: 0,
|
|
height: 0,
|
|
format: 'unknown',
|
|
processed: false
|
|
};
|
|
}
|
|
}
|
|
}
|
|
|
|
export default ImagePreprocessor; |