thumbkit
Version:
A comprehensive TypeScript library for generating thumbnails from images, PDFs, videos, office documents, and archives.
449 lines (324 loc) • 11.8 kB
Markdown
# Universal Thumbnail Generator
A comprehensive TypeScript library for generating thumbnails from various file formats including images, PDFs, videos, office documents, and archives.
## Features
- 🖼️ **Image Support**: JPEG, PNG, GIF, WebP, TIFF, BMP, SVG, AVIF, HEIC, HEIF
- 📄 **Document Support**: PDF, TXT, MD, RTF
- 🎥 **Video Support**: MP4, AVI, MOV, WMV, FLV, WebM, MKV, M4V, 3GP, OGV
- 📊 **Office Support**: DOC, DOCX, XLS, XLSX, PPT, PPTX, ODT, ODS, ODP
- 🗜️ **Archive Support**: ZIP, RAR, 7Z, TAR, GZ, BZ2
- ⚡ **High Performance**: Built with Sharp for fast image processing
- 🛡️ **Type Safe**: Full TypeScript support with comprehensive type definitions
- 🔧 **Configurable**: Extensive configuration options for all output formats
- 📦 **Batch Processing**: Generate multiple thumbnails efficiently
- 🎨 **Multiple Formats**: Output as JPEG, PNG, WebP, or AVIF
## Installation
```bash
npm install universal-thumbnail-generator
```
### Dependencies
The package requires some peer dependencies based on what file types you want to support:
```bash
# For basic image and PDF support (always required)
npm install sharp canvas pdfjs-dist
# For video thumbnail support (optional)
npm install ffmpeg-static
# For office document support (optional)
npm install libreoffice-convert
```
## Quick Start
```typescript
import { UniversalThumbnailGenerator } from "universal-thumbnail-generator";
const generator = new UniversalThumbnailGenerator({
width: 300,
height: 300,
quality: 90,
format: "jpeg",
});
// Generate thumbnail from file path
const result = await generator.generate("./path/to/image.jpg");
// Generate thumbnail from buffer
const fileBuffer = await fs.readFile("./document.pdf");
const result = await generator.generate(fileBuffer, "document.pdf");
// Save the thumbnail
await fs.writeFile(result.fileName, result.fileBuffer);
```
## Configuration Options
```typescript
interface ThumbnailConfig {
width?: number; // Default: 200
height?: number; // Default: 200
quality?: number; // Default: 80 (1-100)
suffix?: string; // Default: '_thumb'
format?: "jpeg" | "png" | "webp" | "avif"; // Default: 'jpeg'
fit?: "cover" | "contain" | "fill" | "inside" | "outside"; // Default: 'inside'
withoutEnlargement?: boolean; // Default: true
background?: {
// Default: white
r: number;
g: number;
b: number;
alpha: number;
};
position?: string; // Default: 'center'
}
```
## Usage Examples
### Basic Usage
```typescript
import { UniversalThumbnailGenerator } from "universal-thumbnail-generator";
const generator = new UniversalThumbnailGenerator();
// From file path
const thumbnail = await generator.generate("./image.jpg");
// From buffer with filename
const buffer = await fs.readFile("./document.pdf");
const thumbnail = await generator.generate(buffer, "document.pdf");
// From FileInput object
const thumbnail = await generator.generate({
buffer: fileBuffer,
fileName: "presentation.pptx",
});
```
### Advanced Configuration
```typescript
const generator = new UniversalThumbnailGenerator({
width: 400,
height: 300,
quality: 95,
format: "webp",
fit: "cover",
background: { r: 240, g: 240, b: 240, alpha: 1 },
suffix: "_preview",
});
const thumbnail = await generator.generate("./video.mp4");
```
### Batch Processing
```typescript
const files = [
"./image1.jpg",
"./document.pdf",
{ buffer: videoBuffer, fileName: "video.mp4" },
];
const batchResult = await generator.generateBatch(files, {
width: 150,
height: 150,
});
console.log(`Generated ${batchResult.results.length} thumbnails`);
console.log(`Failed: ${batchResult.errors.length} files`);
// Process results
batchResult.results.forEach(async (result) => {
await fs.writeFile(`./thumbnails/${result.fileName}`, result.fileBuffer);
});
// Handle errors
batchResult.errors.forEach((error) => {
console.error(`Error processing ${error.fileName}: ${error.error}`);
});
```
### Dynamic Configuration
```typescript
const generator = new UniversalThumbnailGenerator();
// Override config for specific generation
const thumbnail = await generator.generate("./image.jpg", undefined, {
width: 500,
height: 500,
format: "png",
});
// Update global config
generator.updateConfig({
quality: 100,
format: "avif",
});
// Reset to defaults
generator.resetConfig();
```
## File Type Support
### Images
- **Formats**: JPEG, PNG, GIF, WebP, TIFF, BMP, SVG, AVIF, HEIC, HEIF
- **Features**: Full metadata extraction, format conversion, quality control
### Documents
- **PDF**: First page rendering with high quality
- **Text files**: Placeholder thumbnails with file type indicators
### Videos
- **Formats**: MP4, AVI, MOV, WMV, FLV, WebM, MKV, M4V, 3GP, OGV
- **Note**: Currently generates placeholder thumbnails. Full video frame extraction requires ffmpeg integration.
### Office Documents
- **Formats**: Microsoft Office (DOC, DOCX, XLS, XLSX, PPT, PPTX) and OpenDocument (ODT, ODS, ODP)
- **Features**: Color-coded thumbnails based on document type
### Archives
- **Formats**: ZIP, RAR, 7Z, TAR, GZ, BZ2
- **Features**: Distinctive archive-style thumbnails
## API Reference
### Constructor
```typescript
new UniversalThumbnailGenerator(options?: ThumbnailConfig)
```
### Methods
#### `generate(input, fileName?, options?)`
Generate a single thumbnail.
**Parameters:**
- `input`: `Buffer | string | FileInput` - File buffer, path, or FileInput object
- `fileName?`: `string` - Required when input is Buffer
- `options?`: `Partial<ThumbnailConfig>` - Override default config
**Returns:** `Promise<ThumbnailResult>`
#### `generateBatch(files, options?)`
Generate multiple thumbnails.
**Parameters:**
- `files`: `Array<string | FileInput>` - Array of file paths or FileInput objects
- `options?`: `Partial<ThumbnailConfig>` - Override default config
**Returns:** `Promise<BatchResult>`
#### `isSupported(fileName)`
Check if file type is supported.
**Parameters:**
- `fileName`: `string` - File name with extension
**Returns:** `boolean`
#### `getFileType(fileName)`
Get file type category.
**Parameters:**
- `fileName`: `string` - File name with extension
**Returns:** `FileType` - 'image' | 'document' | 'video' | 'office' | 'archive' | 'unsupported'
#### `getSupportedTypes()`
Get all supported file extensions grouped by category.
**Returns:** `SupportedTypes`
#### `getSupportedExtensions()`
Get flat array of all supported extensions.
**Returns:** `string[]`
#### `updateConfig(newConfig)`
Update configuration.
**Parameters:**
- `newConfig`: `Partial<ThumbnailConfig>` - New configuration options
#### `getConfig()`
Get current configuration.
**Returns:** `Required<ThumbnailConfig>`
#### `resetConfig()`
Reset configuration to defaults.
## Response Types
### ThumbnailResult
```typescript
interface ThumbnailResult {
fileName: string; // Generated thumbnail filename
originalFileName: string; // Original file name
fileBuffer: Buffer; // Thumbnail image buffer
fileSizeInBytes: number; // Thumbnail file size
mimeType: string; // Output MIME type
md5Hash: string; // MD5 hash of thumbnail
fileType: FileType; // File type category
dimensions: {
// Thumbnail dimensions
width: number;
height: number;
};
quality: number; // Quality setting used
createdAt: string; // ISO timestamp
isThumbnail: boolean; // Always true
metadata?: Record<string, any>; // Additional metadata
}
```
### BatchResult
```typescript
interface BatchResult {
results: ThumbnailResult[];
errors: Array<{
index: number;
fileName?: string;
error: string;
}>;
}
```
## Error Handling
The library provides detailed error messages for different failure scenarios:
```typescript
try {
const thumbnail = await generator.generate("./invalid-file.xyz");
} catch (error) {
if (error.message.includes("Unsupported file type")) {
console.log("File type not supported");
} else if (error.message.includes("generation failed")) {
console.log("Processing error:", error.message);
}
}
```
## Performance Tips
1. **Batch Processing**: Use `generateBatch()` for multiple files to improve performance
2. **Configuration**: Set configuration once and reuse the generator instance
3. **Format Selection**: Use JPEG for smaller file sizes, PNG for transparency, WebP for modern browsers
4. **Quality Settings**: Lower quality (60-80) significantly reduces file size with minimal visual impact
5. **Size Optimization**: Choose appropriate dimensions based on your use case
## Examples
### Web Server Integration (Express.js)
```typescript
import express from "express";
import multer from "multer";
import { UniversalThumbnailGenerator } from "universal-thumbnail-generator";
const app = express();
const upload = multer();
const generator = new UniversalThumbnailGenerator({
width: 200,
height: 200,
quality: 80,
});
app.post("/upload", upload.single("file"), async (req, res) => {
try {
if (!req.file) {
return res.status(400).json({ error: "No file uploaded" });
}
const thumbnail = await generator.generate(
req.file.buffer,
req.file.originalname
);
res.json({
success: true,
thumbnail: {
fileName: thumbnail.fileName,
size: thumbnail.fileSizeInBytes,
dimensions: thumbnail.dimensions,
},
});
} catch (error) {
res.status(500).json({ error: error.message });
}
});
```
### File Processing Pipeline
```typescript
import { UniversalThumbnailGenerator } from "universal-thumbnail-generator";
import { promises as fs } from "fs";
import path from "path";
async function processDirectory(inputDir: string, outputDir: string) {
const generator = new UniversalThumbnailGenerator({
width: 300,
height: 300,
quality: 85,
format: "webp",
});
const files = await fs.readdir(inputDir);
const supportedFiles = files.filter((file) => generator.isSupported(file));
console.log(`Processing ${supportedFiles.length} supported files...`);
const filePaths = supportedFiles.map((file) => path.join(inputDir, file));
const batchResult = await generator.generateBatch(filePaths);
// Save thumbnails
for (const result of batchResult.results) {
const outputPath = path.join(outputDir, result.fileName);
await fs.writeFile(outputPath, result.fileBuffer);
console.log(`✓ Generated: ${result.fileName}`);
}
// Report errors
for (const error of batchResult.errors) {
console.error(`✗ Failed: ${error.fileName} - ${error.error}`);
}
console.log(
`\nCompleted: ${batchResult.results.length} thumbnails generated`
);
}
```
## Contributing
Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
## License
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
## Changelog
### v1.0.0
- Initial release
- Support for images, PDFs, videos (placeholder), office documents, and archives
- TypeScript support with full type definitions
- Batch processing capabilities
- Comprehensive configuration options
## Support
If you encounter any issues or have questions, please file an issue on the [GitHub repository](https://github.com/yourusername/universal-thumbnail-generator/issues).