API de Formatos de Salida
Sharp soporta múltiples formatos de salida de imágenes, cada uno con sus opciones y usos específicos.
Formato JPEG
Uso Básico
javascript
import sharp from 'sharp';
sharp('input.png')
.jpeg()
.toFile('output.jpg');Opciones JPEG
javascript
sharp('input.png')
.jpeg({
quality: 80, // Calidad (1-100)
progressive: false, // JPEG progresivo
chromaSubsampling: '4:4:4', // Submuestreo de croma
mozjpeg: false, // Usar codificador mozjpeg
trellisQuantisation: false, // Cuantización trellis
overshootDeringing: false, // Eliminación de anillos
optimiseScans: false, // Optimizar escaneos
quantisationTable: 0 // Tabla de cuantización
})
.toFile('output.jpg');Configuración de Calidad
javascript
// Alta calidad
sharp('input.png').jpeg({ quality: 95 })
// Calidad media
sharp('input.png').jpeg({ quality: 80 })
// Baja calidad (archivo pequeño)
sharp('input.png').jpeg({ quality: 50 })Formato PNG
Uso Básico
javascript
sharp('input.jpg')
.png()
.toFile('output.png');Opciones PNG
javascript
sharp('input.jpg')
.png({
progressive: false, // PNG progresivo
compressionLevel: 6, // Nivel de compresión (0-9)
adaptiveFiltering: false, // Filtrado adaptativo
palette: false, // Modo paleta
quality: 100, // Calidad (solo para modo paleta)
colours: 256, // Número de colores (solo para modo paleta)
dither: 0.5, // Dithering (0-1)
force: false // Forzar salida PNG
})
.toFile('output.png');Manejo de Transparencia
javascript
// Mantener transparencia
sharp('input.png')
.png()
.toFile('output.png');
// Agregar fondo blanco
sharp('input.png')
.flatten({ background: { r: 255, g: 255, b: 255 } })
.png()
.toFile('output.png');Formato WebP
Uso Básico
javascript
sharp('input.jpg')
.webp()
.toFile('output.webp');Opciones WebP
javascript
sharp('input.jpg')
.webp({
quality: 80, // Calidad (1-100)
alphaQuality: 100, // Calidad de transparencia (1-100)
lossless: false, // Compresión sin pérdida
nearLossless: false, // Compresión casi sin pérdida
smartSubsample: false, // Submuestreo inteligente
reductionEffort: 4, // Esfuerzo de compresión (0-6)
mixed: false, // Modo mixto
force: false // Forzar salida WebP
})
.toFile('output.webp');WebP Sin Pérdida
javascript
// Compresión sin pérdida
sharp('input.png')
.webp({ lossless: true })
.toFile('output.webp');
// Compresión casi sin pérdida
sharp('input.png')
.webp({ nearLossless: true, quality: 60 })
.toFile('output.webp');Formato AVIF
Uso Básico
javascript
sharp('input.jpg')
.avif()
.toFile('output.avif');Opciones AVIF
javascript
sharp('input.jpg')
.avif({
quality: 80, // Calidad (1-100)
lossless: false, // Compresión sin pérdida
effort: 4, // Esfuerzo de compresión (0-6)
chromaSubsampling: '4:4:4', // Submuestreo de croma
force: false // Forzar salida AVIF
})
.toFile('output.avif');Formato TIFF
Uso Básico
javascript
sharp('input.jpg')
.tiff()
.toFile('output.tiff');Opciones TIFF
javascript
sharp('input.jpg')
.tiff({
quality: 80, // Calidad (1-100)
compression: 'jpeg', // Método de compresión
pyramid: false, // Modo pirámide
tile: false, // Modo mosaico
tileSize: 256, // Tamaño de mosaico
xres: 1, // Resolución X
yres: 1, // Resolución Y
resolutionUnit: 'inch', // Unidad de resolución
force: false // Forzar salida TIFF
})
.toFile('output.tiff');Opciones de Compresión
javascript
// Compresión JPEG
sharp('input.jpg').tiff({ compression: 'jpeg' })
// Compresión LZW
sharp('input.jpg').tiff({ compression: 'lzw' })
// Sin compresión
sharp('input.jpg').tiff({ compression: 'none' })
// Compresión Deflate
sharp('input.jpg').tiff({ compression: 'deflate' })Formato Raw
Salida de Datos de Píxeles Raw
javascript
// Salida de datos raw RGB
const rawData = await sharp('input.jpg')
.raw()
.toBuffer();
// Salida de datos raw RGBA
const rawData = await sharp('input.jpg')
.ensureAlpha()
.raw()
.toBuffer();Salida de Múltiples Formatos
Salida Simultánea de Múltiples Formatos
javascript
const image = sharp('input.jpg').resize(800, 600);
// Salida de múltiples formatos
await Promise.all([
image.clone().jpeg({ quality: 80 }).toFile('output.jpg'),
image.clone().png().toFile('output.png'),
image.clone().webp({ quality: 80 }).toFile('output.webp'),
image.clone().avif({ quality: 80 }).toFile('output.avif')
]);Imágenes Adaptativas
javascript
async function generateResponsiveImages(inputPath) {
const sizes = [320, 640, 1280, 1920];
const formats = ['jpeg', 'webp', 'avif'];
const promises = [];
for (const size of sizes) {
for (const format of formats) {
const image = sharp(inputPath).resize(size);
switch (format) {
case 'jpeg':
promises.push(
image.clone().jpeg({ quality: 80 })
.toFile(`output-${size}.jpg`)
);
break;
case 'webp':
promises.push(
image.clone().webp({ quality: 80 })
.toFile(`output-${size}.webp`)
);
break;
case 'avif':
promises.push(
image.clone().avif({ quality: 80 })
.toFile(`output-${size}.avif`)
);
break;
}
}
}
await Promise.all(promises);
}Detección de Formato
Selección Automática de Formato Según Extensión de Archivo
javascript
function getOutputFormat(filename) {
const ext = filename.split('.').pop().toLowerCase();
switch (ext) {
case 'jpg':
case 'jpeg':
return 'jpeg';
case 'png':
return 'png';
case 'webp':
return 'webp';
case 'avif':
return 'avif';
case 'tiff':
case 'tif':
return 'tiff';
default:
return 'jpeg';
}
}
async function convertImage(inputPath, outputPath) {
const format = getOutputFormat(outputPath);
const image = sharp(inputPath);
switch (format) {
case 'jpeg':
await image.jpeg({ quality: 80 }).toFile(outputPath);
break;
case 'png':
await image.png().toFile(outputPath);
break;
case 'webp':
await image.webp({ quality: 80 }).toFile(outputPath);
break;
case 'avif':
await image.avif({ quality: 80 }).toFile(outputPath);
break;
case 'tiff':
await image.tiff({ compression: 'jpeg' }).toFile(outputPath);
break;
}
}Optimización de Rendimiento
Salida por Streams
javascript
const fs = require('fs');
// Procesamiento por streams
fs.createReadStream('input.jpg')
.pipe(sharp().jpeg({ quality: 80 }))
.pipe(fs.createWriteStream('output.jpg'));Optimización de Memoria
javascript
// Usar Buffer en lugar de archivo
const buffer = await sharp('input.jpg')
.jpeg({ quality: 80 })
.toBuffer();
// Salida directa a respuesta
app.get('/image', async (req, res) => {
const buffer = await sharp('input.jpg')
.resize(300, 200)
.jpeg({ quality: 80 })
.toBuffer();
res.set('Content-Type', 'image/jpeg');
res.send(buffer);
});