Ejemplos Avanzados
Aquí se proporcionan algunos ejemplos de uso avanzado de Sharp, incluyendo operaciones complejas de procesamiento de imágenes.
Composición de Imágenes
Agregar Marca de Agua
javascript
import sharp from 'sharp';
// Agregar marca de agua de texto
await sharp('input.jpg')
.composite([
{
input: Buffer.from(`
<svg width="200" height="100">
<text x="10" y="50" font-family="Arial" font-size="24" fill="white">
Watermark
</text>
</svg>
`),
top: 10,
left: 10
}
])
.jpeg()
.toFile('output.jpg');Superposición de Imágenes
javascript
// Superponer múltiples imágenes
await sharp('background.jpg')
.composite([
{
input: 'overlay1.png',
top: 100,
left: 100
},
{
input: 'overlay2.png',
top: 200,
left: 200
}
])
.jpeg()
.toFile('output.jpg');Operaciones de Canales
Separar Canales
javascript
// Separar canales RGB
const channels = await sharp('input.jpg').separate();
// Guardar cada canal
await sharp(channels[0]).toFile('red-channel.jpg');
await sharp(channels[1]).toFile('green-channel.jpg');
await sharp(channels[2]).toFile('blue-channel.jpg');Combinar Canales
javascript
// Combinar desde archivos de canales separados
await sharp('red-channel.jpg')
.joinChannel(['green-channel.jpg', 'blue-channel.jpg'])
.toFile('merged.jpg');Conversión de Espacios de Color
RGB a CMYK
javascript
await sharp('input.jpg')
.toColourspace(sharp.colourspace.cmyk)
.tiff()
.toFile('output.tiff');Convertir a Espacio de Color Lab
javascript
await sharp('input.jpg')
.toColourspace(sharp.colourspace.lab)
.tiff()
.toFile('output.tiff');Filtros Avanzados
Nitidez Personalizada
javascript
await sharp('input.jpg')
.sharpen({
sigma: 1,
flat: 1,
jagged: 2
})
.toFile('output.jpg');Corrección Gamma
javascript
await sharp('input.jpg')
.gamma(2.2)
.toFile('output.jpg');Tinte
javascript
await sharp('input.jpg')
.tint({ r: 255, g: 0, b: 0 })
.toFile('output.jpg');Procesamiento de Imágenes Multipágina
Procesar TIFF Multipágina
javascript
// Procesar todas las páginas
await sharp('multi-page.tiff', { pages: -1 })
.resize(800, 600)
.tiff()
.toFile('output.tiff');
// Procesar página específica
await sharp('multi-page.tiff', { pages: 0 })
.resize(800, 600)
.jpeg()
.toFile('page0.jpg');Procesar PDF
javascript
// Procesar primera página de PDF
await sharp('document.pdf', { pages: 0 })
.resize(800, 600)
.jpeg()
.toFile('page0.jpg');Generación de Imágenes Adaptativas
Generar Múltiples Tamaños
javascript
async function generateResponsiveImages(inputPath) {
const sizes = [
{ width: 320, height: 240, suffix: 'small' },
{ width: 640, height: 480, suffix: 'medium' },
{ width: 1280, height: 960, suffix: 'large' },
{ width: 1920, height: 1440, suffix: 'xlarge' }
];
const promises = sizes.map(async ({ width, height, suffix }) => {
await sharp(inputPath)
.resize(width, height, { fit: 'cover' })
.jpeg({ quality: 80 })
.toFile(`output-${suffix}.jpg`);
});
await Promise.all(promises);
}Generar Múltiples Formatos
javascript
async function generateMultipleFormats(inputPath) {
const formats = [
{ format: 'jpeg', quality: 80, ext: 'jpg' },
{ format: 'webp', quality: 80, ext: 'webp' },
{ format: 'avif', quality: 80, ext: 'avif' }
];
const promises = formats.map(async ({ format, quality, ext }) => {
const image = sharp(inputPath).resize(800, 600);
switch (format) {
case 'jpeg':
await image.jpeg({ quality }).toFile(`output.${ext}`);
break;
case 'webp':
await image.webp({ quality }).toFile(`output.${ext}`);
break;
case 'avif':
await image.avif({ quality }).toFile(`output.${ext}`);
break;
}
});
await Promise.all(promises);
}Análisis de Imágenes
Obtener Información Estadística de Imagen
javascript
async function analyzeImage(filePath) {
const metadata = await sharp(filePath).metadata();
const stats = await sharp(filePath).stats();
return {
metadata,
stats: {
isOpaque: stats.isOpaque,
dominant: stats.dominant,
channels: stats.channels
}
};
}Detectar Tipo de Imagen
javascript
async function detectImageType(filePath) {
const metadata = await sharp(filePath).metadata();
return {
format: metadata.format,
hasAlpha: metadata.hasAlpha,
isOpaque: metadata.isOpaque,
channels: metadata.channels,
colorSpace: metadata.space
};
}Recorte Avanzado
Recorte Inteligente
javascript
async function smartCrop(inputPath, outputPath, width, height) {
// Obtener información de imagen
const metadata = await sharp(inputPath).metadata();
// Calcular región de recorte
const aspectRatio = width / height;
const imageAspectRatio = metadata.width / metadata.height;
let cropWidth, cropHeight, left, top;
if (aspectRatio > imageAspectRatio) {
// Objetivo más ancho, usar altura como referencia
cropHeight = metadata.height;
cropWidth = cropHeight * aspectRatio;
top = 0;
left = (metadata.width - cropWidth) / 2;
} else {
// Objetivo más alto, usar ancho como referencia
cropWidth = metadata.width;
cropHeight = cropWidth / aspectRatio;
left = 0;
top = (metadata.height - cropHeight) / 2;
}
await sharp(inputPath)
.extract({ left: Math.round(left), top: Math.round(top), width: Math.round(cropWidth), height: Math.round(cropHeight) })
.resize(width, height)
.toFile(outputPath);
}Optimización de Imágenes
Optimización Automática
javascript
async function autoOptimize(inputPath, outputPath) {
const metadata = await sharp(inputPath).metadata();
let image = sharp(inputPath);
// Seleccionar mejor formato según tipo de imagen
if (metadata.hasAlpha) {
// Tiene transparencia, usar PNG
image = image.png();
} else {
// Sin transparencia, usar JPEG
image = image.jpeg({ quality: 80, progressive: true });
}
await image.toFile(outputPath);
}JPEG Progresivo
javascript
await sharp('input.jpg')
.jpeg({
quality: 80,
progressive: true,
mozjpeg: true
})
.toFile('output.jpg');Procesamiento Avanzado por Lotes
Marca de Agua por Lotes
javascript
const fs = require('fs').promises;
async function batchWatermark(inputDir, outputDir, watermarkPath) {
const files = await fs.readdir(inputDir);
for (const file of files) {
if (file.match(/\.(jpg|jpeg|png|webp)$/i)) {
try {
await sharp(path.join(inputDir, file))
.composite([
{
input: watermarkPath,
top: 10,
left: 10
}
])
.jpeg({ quality: 80 })
.toFile(path.join(outputDir, `watermarked_${file}`));
console.log(`Marca de agua agregada: ${file}`);
} catch (error) {
console.error(`Error al procesar ${file}:`, error.message);
}
}
}
}Conversión y Optimización por Lotes
javascript
async function batchOptimize(inputDir, outputDir) {
const files = await fs.readdir(inputDir);
for (const file of files) {
if (file.match(/\.(jpg|jpeg|png|webp)$/i)) {
try {
const metadata = await sharp(path.join(inputDir, file)).metadata();
const image = sharp(path.join(inputDir, file));
// Seleccionar mejor formato según características de imagen
if (metadata.hasAlpha) {
await image.png({ compressionLevel: 9 }).toFile(path.join(outputDir, file.replace(/\.[^.]+$/, '.png')));
} else {
await image.jpeg({ quality: 80, progressive: true }).toFile(path.join(outputDir, file.replace(/\.[^.]+$/, '.jpg')));
}
console.log(`Optimización completada: ${file}`);
} catch (error) {
console.error(`Error al procesar ${file}:`, error.message);
}
}
}
}