Ví dụ nâng cao
Đây là một số ví dụ sử dụng nâng cao của Sharp, bao gồm các thao tác xử lý hình ảnh phức tạp.
Tổng hợp hình ảnh
Thêm watermark
javascript
import sharp from 'sharp';
// Thêm watermark văn bản
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');Chồng hình ảnh
javascript
// Chồng nhiều hình ảnh
await sharp('background.jpg')
.composite([
{
input: 'overlay1.png',
top: 100,
left: 100
},
{
input: 'overlay2.png',
top: 200,
left: 200
}
])
.jpeg()
.toFile('output.jpg');Thao tác kênh
Tách kênh
javascript
// Tách kênh RGB
const channels = await sharp('input.jpg').separate();
// Lưu từng kênh
await sharp(channels[0]).toFile('red-channel.jpg');
await sharp(channels[1]).toFile('green-channel.jpg');
await sharp(channels[2]).toFile('blue-channel.jpg');Hợp nhất kênh
javascript
// Hợp nhất từ các tệp kênh riêng biệt
await sharp('red-channel.jpg')
.joinChannel(['green-channel.jpg', 'blue-channel.jpg'])
.toFile('merged.jpg');Chuyển đổi không gian màu
RGB sang CMYK
javascript
await sharp('input.jpg')
.toColourspace(sharp.colourspace.cmyk)
.tiff()
.toFile('output.tiff');Chuyển đổi sang không gian màu Lab
javascript
await sharp('input.jpg')
.toColourspace(sharp.colourspace.lab)
.tiff()
.toFile('output.tiff');Bộ lọc nâng cao
Làm sắc nét tùy chỉnh
javascript
await sharp('input.jpg')
.sharpen({
sigma: 1,
flat: 1,
jagged: 2
})
.toFile('output.jpg');Hiệu chỉnh gamma
javascript
await sharp('input.jpg')
.gamma(2.2)
.toFile('output.jpg');Tách sắc độ
javascript
await sharp('input.jpg')
.tint({ r: 255, g: 0, b: 0 })
.toFile('output.jpg');Xử lý hình ảnh nhiều trang
Xử lý TIFF nhiều trang
javascript
// Xử lý tất cả các trang
await sharp('multi-page.tiff', { pages: -1 })
.resize(800, 600)
.tiff()
.toFile('output.tiff');
// Xử lý trang cụ thể
await sharp('multi-page.tiff', { pages: 0 })
.resize(800, 600)
.jpeg()
.toFile('page0.jpg');Xử lý PDF
javascript
// Xử lý trang đầu tiên của PDF
await sharp('document.pdf', { pages: 0 })
.resize(800, 600)
.jpeg()
.toFile('page0.jpg');Tạo hình ảnh đáp ứng
Tạo nhiều kích thước
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);
}Tạo nhiều định dạng
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);
}Phân tích hình ảnh
Lấy thông tin thống kê hình ảnh
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
}
};
}Phát hiện loại hình ảnh
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
};
}Cắt nâng cao
Cắt thông minh
javascript
async function smartCrop(inputPath, outputPath, width, height) {
// Lấy thông tin hình ảnh
const metadata = await sharp(inputPath).metadata();
// Tính toán vùng cắt
const aspectRatio = width / height;
const imageAspectRatio = metadata.width / metadata.height;
let cropWidth, cropHeight, left, top;
if (aspectRatio > imageAspectRatio) {
// Mục tiêu rộng hơn, lấy chiều cao làm chuẩn
cropHeight = metadata.height;
cropWidth = cropHeight * aspectRatio;
top = 0;
left = (metadata.width - cropWidth) / 2;
} else {
// Mục tiêu cao hơn, lấy chiều rộng làm chuẩn
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);
}Tối ưu hóa hình ảnh
Tự động tối ưu hóa
javascript
async function autoOptimize(inputPath, outputPath) {
const metadata = await sharp(inputPath).metadata();
let image = sharp(inputPath);
// Chọn định dạng tốt nhất theo loại hình ảnh
if (metadata.hasAlpha) {
// Có độ trong suốt, sử dụng PNG
image = image.png();
} else {
// Không có độ trong suốt, sử dụng JPEG
image = image.jpeg({ quality: 80, progressive: true });
}
await image.toFile(outputPath);
}JPEG lũy tiến
javascript
await sharp('input.jpg')
.jpeg({
quality: 80,
progressive: true,
mozjpeg: true
})
.toFile('output.jpg');Xử lý hàng loạt nâng cao
Watermark hàng loạt
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(`Hoàn tất thêm watermark: ${file}`);
} catch (error) {
console.error(`Xử lý thất bại ${file}:`, error.message);
}
}
}
}Chuyển đổi và tối ưu hóa định dạng hàng loạt
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));
// Chọn định dạng tốt nhất theo đặc tính hình ảnh
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(`Tối ưu hóa hoàn tất: ${file}`);
} catch (error) {
console.error(`Xử lý thất bại ${file}:`, error.message);
}
}
}
}