discord-image-utils
Version:
A powerful library for generating and modifying images with Discord.js - includes meme generation, filters, effects and animations
649 lines (529 loc) • 18.7 kB
Markdown
# Discord Image Generation
This package is a reimplementation of [discord-image-generation](https://www.npmjs.com/package/discord-image-generation), enhanced with additional features . While inspired by the original package, it has been completely rewritten to provide better TypeScript support, improved performance, and compatibility .
# Discord Image Generation
A TypeScript library for generating and modifying images for use with Discord.js.
## Features
- Generate GIFs and static images
- Apply filters (blur, grayscale, sepia, invert, gay)
- Create animated effects (blink, triggered)
- Wide variety of meme generators and image manipulations:
- Drake Meme Generator
- Wave Effect Animation
- Glitch Effect Filter
- Sticker Effect Filter
- RankCard/Level System with multiple layouts (NEW!)
- Affect, Wanted, Kiss, Tatoo
- Batslap, Ad, Beautiful, Bed
- Clown, Hitler, Trash, Stonk/NotStonk
- Spank, Snyder, RIP
- Lisa Presentation, Jail
- Heartbreaking, Facepalm
- Double Stonk, Confused Stonk
- Deepfry, Bob Ross
- Music Player Image Generator
- Quote Image Generator with Custom Styles
- Compatible with Discord.js v14+
- Highly customizable image handling
## Installation
```bash
# Using npm
npm install discord-image-utils
# Using yarn
yarn add discord-image-utils
# Using pnpm
pnpm add discord-image-utils
```
## Enhanced Module Structure & TypeScript Support
This library now features a comprehensive module system with excellent TypeScript support and multiple import options:
### Import Options
```typescript
// 1. Named imports (recommended)
import { blur, wanted, WelcomeCardBuilder } from 'discord-image-utils';
// 2. Category-specific imports (best for bundle size)
import { blur, greyscale, pixelate } from 'discord-image-utils/filters';
import { triggered, blink } from 'discord-image-utils/gif';
import { wanted, affect } from 'discord-image-utils/image';
import { welcomeCard, level } from 'discord-image-utils/fun';
// 3. Type-only imports
import type {
WelcomeCardOptions,
FilterLevel,
ValidationError
} from 'discord-image-utils/types';
// 4. Error handling classes
import {
ValidationError,
NetworkError,
ImageProcessingError
} from 'discord-image-utils/errors';
// 5. Traditional default import (still supported)
import dig from 'discord-image-utils';
```
### Enhanced Error Handling
```typescript
import { blur, ValidationError, ImageProcessingError } from 'discord-image-utils';
try {
const result = await blur(image, 5);
} catch (error) {
if (error instanceof ValidationError) {
console.log(`Validation error: ${error.message}`);
console.log(`Field: ${error.details?.field}`);
} else if (error instanceof ImageProcessingError) {
console.log(`Processing error: ${error.message}`);
console.log(`Operation: ${error.details?.operation}`);
}
}
```
## Quick Start
```typescript
import { AttachmentBuilder } from 'discord.js';
import { blur, triggered, wanted } from 'discord-image-utils';
// Example: Using in a Discord.js command
async function imageCommand(message, imageUrl) {
try {
// Apply a filter with enhanced error handling
const blurredImage = await blur(imageUrl, 5);
const attachment = new AttachmentBuilder(blurredImage, { name: 'blurred.png' });
await message.reply({ files: [attachment] });
// Create a GIF
const triggeredGif = await triggered(imageUrl);
const gifAttachment = new AttachmentBuilder(triggeredGif, { name: 'triggered.gif' });
await message.reply({ files: [gifAttachment] });
} catch (error) {
console.error('Error processing image:', error);
// Error handling is now much more detailed and helpful
}
}
```
## API Reference
### Filters
All filter functions return a Promise that resolves to a Buffer containing the modified image.
#### `blur(intensity: number, imageUrl: string): Promise<Buffer>`
Applies a Gaussian blur effect to the image.
- `intensity`: Blur intensity (1-20)
- `imageUrl`: URL or file path of the source image
#### `gay(imageUrl: string): Promise<Buffer>`
Applies a rainbow overlay effect.
#### `greyscale(imageUrl: string): Promise<Buffer>`
Converts the image to grayscale.
#### `invert(imageUrl: string): Promise<Buffer>`
Inverts the colors of the image.
#### `sepia(imageUrl: string): Promise<Buffer>`
Applies a sepia tone effect.
### GIF Generators
#### `blink(delay: number, imageUrl1: string, imageUrl2: string): Promise<Buffer>`
Creates a blinking effect between two images.
- `delay`: Time in milliseconds between frames
- `imageUrl1`: First image URL/path
- `imageUrl2`: Second image URL/path
#### `triggered(imageUrl: string): Promise<Buffer>`
Creates a "triggered" meme GIF.
### Image Manipulations
#### `wanted(imageUrl: string): Promise<Buffer>`
Creates a "wanted" poster with the image.
#### `kiss(image1Url: string, image2Url: string): Promise<Buffer>`
Creates a kissing scene with two images.
#### `Batslap(image1Url: string, image2Url: string): Promise<Buffer>`
Creates a Batman slapping meme with two images.
#### `stonk(imageUrl: string): Promise<Buffer>`
Creates a "stonks" meme with the image.
#### `notStonk(imageUrl: string): Promise<Buffer>`
Creates a "not stonks" meme with the image.
#### `lisaPresentation(text: string): Promise<Buffer>`
Creates a Lisa Simpson presentation meme with custom text.
### Sticker Effect
#### `sticker(image: ImageInput, borderSize?: number): Promise<Buffer>`
Applies a sticker effect with white border and drop shadow to an image.
- `image`: URL or file path of the source image
- `borderSize`: Size of the white border (5-50, default: 15)
Example:
```typescript
const stickerImage = await sticker(userAvatarUrl, 20);
```
### RankCard/Level System
#### `RankCard`: Class for Creating Dynamic Level Cards
Creates customizable rank/level cards with various layouts, themes, and visual elements. Perfect for Discord bots with leveling systems.
```typescript
import { RankCard } from 'discord-image-utils';
// Create a basic rank card
const card = new RankCard({
name: "Username",
level: 10,
avatar: "https://example.com/avatar.png", // URL or Buffer
xp: 750,
maxXp: 1000,
theme: "neon"
});
// Customize with chainable methods
card.setProgressBarGradient([
{ color: "#ff00ff", position: 0 },
{ color: "#00ffff", position: 1 }
])
.setAvatarGlow("#ff00ff")
.setLayout("futuristicHUD");
// Render the card
const buffer = await card.render();
```
#### Layouts
The RankCard supports multiple layout designs:
- `classic`: Standard card layout with rounded corners
- `futuristicHUD`: Sci-fi themed layout with hexagonal elements and HUD-style display
- `split`: Two-column layout (avatar | stats)
- `ribbon`: Trophy-style card with decorative elements
- `diagonal`: Angular layout with diagonal division
- `stacked`: Layered design with overlapping elements
#### Themes
Built-in themes that affect colors and generated backgrounds:
- `default`: Clean, modern design
- `futuristic`: Tech-inspired with circuit patterns
- `neon`: Dark theme with glowing elements
- `minimal`: Simple, light design with subtle patterns
- `aurora`: Space-inspired with flowing aurora effects
- `sunset`: Warm tones with ray patterns
#### Customization Options
```typescript
interface LevelOptions {
// Basic info
name: string; // Username
level: number; // Level number
avatar: ImageInput; // Avatar URL/Buffer or Discord user object
xp: number; // Current XP
maxXp: number; // XP required for current level
nextLevelXp?: number; // XP for next level
levelUpXp?: number; // XP needed to level up
progress?: number; // Override progress calculation (0-1)
// Layout and theme
layout?: LayoutType; // Card layout design
theme?: ThemeName; // Preset color theme
// Display options
showNextLevelXp?: boolean; // Show next level XP info
showLevelUpXp?: boolean; // Show XP needed to level up
maxNameWidth?: number; // Max width for username display
// Visual customization
progressBarColor?: string;
progressBarGradient?: GradientStop[];
textColor?: string;
fontSize?: number;
bold?: boolean;
fontFamily?: string;
textEffect?: TextEffectOptions;
// Background
backgroundBlur?: number;
backgroundOverlay?: string;
backgroundImage?: ImageInput;
// Avatar
avatarGlow?: string;
avatarGlowIntensity?: number;
avatarSize?: number;
avatarBorder?: string;
avatarBorderWidth?: number;
}
```
Example with Futuristic HUD layout:
```typescript
const rankCard = new RankCard({
name: "COMMANDER_01",
level: 42,
avatar: message.author, // Discord.js user object
xp: 8750,
maxXp: 10000,
theme: "futuristic",
layout: "futuristicHUD",
avatarGlow: "#00FFFF",
avatarGlowIntensity: 25
});
const attachment = new AttachmentBuilder(await rankCard.render(), { name: 'rank.png' });
await message.reply({ files: [attachment] });
```
### Welcome Card Generator
#### `welcomeCard`: Function for Creating Server Welcome Images
Creates customizable welcome images for greeting new members in Discord servers.
```typescript
import { welcomeCard } from 'discord-image-utils';
// Create a basic welcome card
const card = await welcomeCard({
username: "NewUser",
avatar: "https://example.com/avatar.png", // URL or Buffer
servername: "My Awesome Server",
memberCount: 42,
theme: "default"
});
// Use the card in Discord.js
const attachment = new AttachmentBuilder(card, { name: 'welcome.png' });
await channel.send({ files: [attachment] });
```
#### Using the Builder API
```typescript
import { WelcomeCardBuilder } from 'discord-image-utils';
// Create a welcome card using the builder pattern
const card = new WelcomeCardBuilder()
.setUsername("NewUser")
.setAvatar("https://example.com/avatar.png")
.setServerName("My Awesome Server")
.setMemberCount(42)
.setTheme("tech")
.setMessage("Welcome aboard! Enjoy your stay!")
.setBackground("https://example.com/background.png")
.setTextColor("#FFFFFF");
// Render the card
const buffer = await card.render();
```
#### Available Themes
- `default`: Modern dark design with blue accents
- `dark`: Dark theme with Discord purple accents
- `light`: Light theme with Discord purple accents
- `colorful`: Vibrant blue background with orange accents
- `minimal`: Clean white design with subtle borders
- `tech`: Futuristic dark theme with cyan text and HUD-like elements
#### Customization Options
```typescript
interface WelcomeCardOptions {
username: string; // Username to display
avatar: ImageInput; // Avatar URL or Buffer
servername?: string; // Server name to display
memberCount?: number; // Member count to display (#42)
background?: ImageInput; // Custom background image
theme?: WelcomeTheme; // Predefined theme
message?: string; // Custom welcome message
customization?: { // Advanced style options
textColor?: string;
borderColor?: string;
backgroundColor?: string;
avatarBorderColor?: string;
font?: string;
fontSize?: number;
}
}
```
## Advanced Usage
## Fun
### Drake Meme Generator
#### `drake(text1: string, text2: string, options?: DrakeOptions): Promise<Buffer>`
Creates a Drake meme with customizable text and styling.
Options:
```typescript
interface DrakeOptions {
fontSize?: number; // Text size (default: 32)
textColor?: string; // Text color (default: "#000000")
bold?: boolean; // Use bold text (default: true)
maxWidth?: number; // Max text width before wrapping (default: 300)
padding?: number; // Text padding from edges (default: 20)
}
```
Example:
```typescript
const drakeMeme = await drake(
"Using complex code",
"Using simple solutions",
{
fontSize: 36,
textColor: "#333333",
bold: true
}
);
```
### Wave Effect
#### `wave(image: ImageInput, options?: WaveOptions): Promise<Buffer>`
Applies a wave distortion effect to an image.
Options:
```typescript
interface WaveOptions {
amplitude?: number; // Wave height (1-50, default: 10)
frequency?: number; // Wave frequency (1-20, default: 5)
phase?: number; // Wave phase (0-360, default: 0)
direction?: "horizontal" | "vertical" | "both"; // Wave direction (default: "both")
}
```
Example:
```typescript
const wavedImage = await wave(imageUrl, {
amplitude: 15,
frequency: 8,
direction: "horizontal"
});
```
### Glitch Effect
#### `glitch(image: ImageInput, intensity?: number): Promise<Buffer>`
Creates a digital glitch art effect with RGB channel shifts and visual corruption.
- `image`: URL or file path of the source image
- `intensity`: Glitch intensity (1-10, default: 5)
Example:
```typescript
const glitchedImage = await glitch(userAvatarUrl, 7);
```
### Music Image Generator
#### `Music(options: MusicImageOptions): Promise<Buffer>`
Creates a stylized music player image with album art and progress bar, perfect for Discord music bots and rich presence displays.
Options:
```typescript
interface MusicImageOptions {
image: string; // URL or path of album artwork
title: string; // Song title
artist: string; // Artist name
time: {
currentTime: number; // Current playback time in seconds
totalTime: number; // Total song duration in seconds
};
progressBar?: {
color?: string; // Progress bar color (default: "#ffffff")
backgroundColor?: string; // Background color (default: "#000000")
width?: number; // Bar width in pixels (default: 300)
height?: number; // Bar height in pixels (default: 10)
rounded?: boolean; // Rounded corners (default: true)
};
background?: {
type?: "blur" | "gradient" | "solid"; // Background style
color?: string; // For solid background
gradient?: string[]; // For gradient background
blurAmount?: number; // For blur background (1-20)
};
font?: {
title?: string; // Title font family
artist?: string; // Artist font family
time?: string; // Time font family
};
}
```
Example:
```typescript
const musicCard = await Music({
image: "https://example.com/album-art.jpg",
title: "Never Gonna Give You Up",
artist: "Rick Astley",
time: {
currentTime: 42,
totalTime: 213
},
progressBar: {
color: "#ff0000",
backgroundColor: "#333333",
rounded: true
},
background: {
type: "gradient",
gradient: ["#1e1e1e", "#2d2d2d"]
}
});
```
### Quote Image Generator
#### `quote(options: QuoteOptions): Promise<Buffer>`
Creates beautifully styled quote images with customizable typography, backgrounds, and visual effects.
Options:
```typescript
interface QuoteOptions {
quote: string; // The quote text
author?: string; // Quote author (optional)
style?: {
theme?: "light" | "dark" | "minimal" | "elegant";
fontFamily?: string; // Custom font for quote text
fontSize?: number; // Base font size
textAlign?: "left" | "center" | "right";
padding?: number; // Padding around text
};
background?: {
type: "gradient" | "pattern" | "solid" | "image";
gradient?: {
type: "linear" | "radial";
colors: string[]; // Array of color values
angle?: number; // For linear gradients (0-360)
};
pattern?: {
type: "dots" | "lines" | "grid" | "waves" | "chevron";
color?: string;
opacity?: number; // Pattern opacity (0-1)
scale?: number; // Pattern size multiplier
};
image?: string; // URL for background image
color?: string; // For solid backgrounds
};
effects?: {
shadow?: boolean; // Text shadow effect
glow?: boolean; // Text glow effect
blur?: number; // Background blur amount
vignette?: boolean; // Vignette effect
noise?: number; // Noise overlay amount (0-1)
};
dimensions?: {
width?: number; // Output image width
height?: number; // Output image height
aspectRatio?: string; // Or use aspect ratio (e.g., "16:9")
};
}
```
Example:
```typescript
const quoteImage = await quote({
quote: "Be the change you wish to see in the world.",
author: "Mahatma Gandhi",
style: {
theme: "elegant",
fontFamily: "Playfair Display",
textAlign: "center"
},
background: {
type: "gradient",
gradient: {
type: "linear",
colors: ["#2193b0", "#6dd5ed"],
angle: 45
}
},
effects: {
shadow: true,
glow: true,
vignette: true
},
dimensions: {
aspectRatio: "1:1"
}
});
```
### Custom Options
Many functions accept an optional configuration object:
```typescript
interface ImageOptions {
width?: number; // Output width
height?: number; // Output height
quality?: number; // Image quality (1-100)
format?: string; // Output format ('png' | 'jpeg' | 'gif')
background?: string; // Background color (CSS color string)
}
// Example with options
const customImage = await wanted(imageUrl, {
width: 800,
height: 600,
quality: 90,
format: 'png'
});
```
### Error Handling
```typescript
try {
const image = await blur(5, imageUrl);
} catch (error) {
if (error.message.includes('INVALID_URL')) {
console.error('Invalid image URL provided');
} else if (error.message.includes('UNSUPPORTED_FORMAT')) {
console.error('Unsupported image format');
} else {
console.error('An error occurred:', error);
}
}
```
## Contributing
Contributions are welcome! Please read our [Contributing Guide](CONTRIBUTING.md) for details on our code of conduct and the process for submitting pull requests.
1. Fork the repository
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
3. Commit your changes (`git commit -m 'Add some amazing feature'`)
4. Push to the branch (`git push origin feature/amazing-feature`)
5. Open a Pull Request
## License
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
## Support
If you encounter any issues or have questions:
1. Check the [GitHub Issues](https://github.com/GrishMahat/discord-image/issues) for existing problems/questions
2. Create a new issue if your problem hasn't been reported
## Acknowledgments
- Original inspiration from [discord-image-generation](https://www.npmjs.com/package/discord-image-generation)
- Built with [Canvas](https://www.npmjs.com/package/canvas) and [GIFEncoder](https://www.npmjs.com/package/gifencoder)
- Thanks to all contributors who have helped shape this project