Files
rx.scoreodonto.com/dental-server/image-processor.js
T
2026-05-30 15:51:48 +02:00

189 lines
4.9 KiB
JavaScript

const sharp = require('sharp');
const fs = require('fs').promises;
const path = require('path');
class ImageProcessor {
constructor() {
this.supportedFormats = ['png', 'jpg', 'jpeg'];
this.maxImageSize = 10 * 1024 * 1024; // 10MB
}
// ================================================================
// MÉTODOS EXISTENTES (se já existirem no servidor)
// ================================================================
async process(imageBuffer, options = {}) {
let pipeline = sharp(imageBuffer);
// Ajustar brilho
if (options.brightness !== undefined) {
pipeline = pipeline.modulate({
brightness: options.brightness
});
}
// Ajustar contraste
if (options.contrast !== undefined) {
pipeline = pipeline.modulate({
brightness: options.contrast
});
}
// Ajustar saturação
if (options.saturation !== undefined) {
pipeline = pipeline.modulate({
saturation: options.saturation
});
}
return await pipeline.png().toBuffer();
}
// ================================================================
// NOVOS MÉTODOS - ROTAÇÃO E FLIP
// ================================================================
async rotate(imageBuffer, degrees) {
try {
if (degrees === 0) return imageBuffer;
const sharp = require('sharp');
return await sharp(imageBuffer)
.rotate(degrees)
.png()
.toBuffer();
} catch (error) {
console.error('Erro na rotação:', error);
throw error;
}
}
async flip(imageBuffer, horizontal, vertical) {
try {
const sharp = require('sharp');
let pipeline = sharp(imageBuffer);
if (horizontal) {
pipeline = pipeline.flop();
}
if (vertical) {
pipeline = pipeline.flip();
}
return await pipeline.png().toBuffer();
} catch (error) {
console.error('Erro no flip:', error);
throw error;
}
}
async rotateAndFlip(imageBuffer, options = {}) {
try {
let pipeline = sharp(imageBuffer);
if (options.rotation && options.rotation !== 0) {
pipeline = pipeline.rotate(options.rotation);
}
if (options.flipH) {
pipeline = pipeline.flop();
}
if (options.flipV) {
pipeline = pipeline.flip();
}
return await pipeline.png().toBuffer();
} catch (error) {
console.error('Erro ao rotacionar e flipar:', error);
throw error;
}
}
// ================================================================
// MÉTODOS DE UTILIDADE
// ================================================================
async getThumbnail(imageBuffer, width = 500, height = 500) {
try {
const sharp = require('sharp');
return await sharp(imageBuffer)
.resize(width, height, {
fit: 'inside',
withoutEnlargement: true
})
.jpeg({ quality: 80, force: true })
.toBuffer();
} catch (error) {
console.error('Erro ao gerar thumbnail:', error);
throw error;
}
}
async getBase64Preview(imageBuffer, maxSize = 300) {
try {
const thumbnail = await this.getThumbnail(imageBuffer, maxSize, maxSize);
return `data:image/png;base64,${thumbnail.toString('base64')}`;
} catch (error) {
console.error('Erro ao gerar preview base64:', error);
throw error;
}
}
async validateImage(imageBuffer) {
try {
const metadata = await sharp(imageBuffer).metadata();
if (!metadata.format || !this.supportedFormats.includes(metadata.format.toLowerCase())) {
throw new Error(`Formato não suportado: ${metadata.format}`);
}
if (imageBuffer.length > this.maxImageSize) {
throw new Error(`Imagem muito grande: ${(imageBuffer.length / 1024 / 1024).toFixed(2)}MB`);
}
return true;
} catch (error) {
console.error('Erro na validação:', error);
throw error;
}
}
async resize(imageBuffer, width, height, options = {}) {
try {
const sharp = require('sharp');
return await sharp(imageBuffer)
.resize(width, height, {
fit: options.fit || 'inside',
withoutEnlargement: true
})
.png()
.toBuffer();
} catch (error) {
console.error('Erro no resize:', error);
throw error;
}
}
async getImageMetadata(imageBuffer) {
try {
const sharp = require('sharp');
const metadata = await sharp(imageBuffer).metadata();
return {
format: metadata.format,
width: metadata.width,
height: metadata.height,
size: imageBuffer.length,
channels: metadata.channels,
hasAlpha: metadata.hasAlpha
};
} catch (error) {
console.error('Erro ao ler metadata:', error);
throw error;
}
}
}
// Exportar instância singleton
module.exports = new ImageProcessor();