phantom-canva
v1.0.0
Published
Advanced canvas image generation for welcome (wlc) and goodbye (gdb) images with 5 styles each
Maintainers
Readme
Phantom-Canva
https://img.shields.io/npm/v/phantom-canva https://img.shields.io/npm/dm/phantom-canva https://img.shields.io/npm/l/phantom-canva https://img.shields.io/node/v/phantom-canva
Advanced Canvas Image Generation Library for Welcome & Goodbye Images
Generate stunning welcome and goodbye images with 5 different styles each. Perfect for Discord bots, community platforms, and any application needing dynamic visual greetings or farewells.
Installation • Usage • API Reference • Examples • License
✨ Features
· 🎨 5 Welcome Styles - From simple to stylized welcome images · 👋 5 Goodbye Styles - Various farewell image designs · 🖼️ URL & File Upload Support - Use image URLs or direct file buffers · ⚡ High Performance - Optimized canvas rendering · 🎯 Easy to Use - Simple function calls with clear parameters · 📦 Lightweight - Minimal dependencies, maximum output · 🔧 Customizable - Quality settings, text sizing, and more
📦 Installation
npm install phantom-canvaDependencies
This package requires the following peer dependencies:
npm install canvas @putuofc/assetsku canvafy axios file-type🚀 Quick Start
const { wlc5, gdb5 } = require('phantom-canva');
// Generate a welcome image
const welcomeImage = await wlc5(
'JohnDoe', // username
'Gaming Community', // guild name
1234, // member count
'https://example.com/avatar.jpg', // avatar URL
'https://example.com/bg.jpg', // background URL
90 // quality (optional)
);
// Generate a goodbye image
const goodbyeImage = await gdb5(
'JohnDoe', // username
'Gaming Community', // guild name
1234, // member count
'https://example.com/avatar.jpg', // avatar URL
'https://example.com/bg.jpg', // background URL
90 // quality (optional)
);
// Use the buffers (e.g., send as response, save to disk, etc.)
require('fs').writeFileSync('welcome.jpg', welcomeImage);
require('fs').writeFileSync('goodbye.jpg', goodbyeImage);📚 API Reference
Welcome Images (wlc1 - wlc5)
wlc1(username, guildName, guildIcon, memberCount, avatar, background, quality?)
Stylized welcome image with guild icon
Parameter Type Required Description username string ✅ Username to display (max 25 chars) guildName string ✅ Guild/server name (max 30 chars) guildIcon string/Buffer ✅ Guild icon URL or buffer memberCount number ✅ Member count (positive number) avatar string/Buffer ✅ User avatar URL or buffer background string/Buffer ✅ Background image URL or buffer quality number ❌ JPEG quality 1-100 (default: 100)
Returns: Promise
wlc2(username, guildName, memberCount, avatar, background)
Welcome image with rotated frame design
Parameter Type Required Description username string ✅ Username to display (max 25 chars) guildName string ✅ Guild/server name (max 50 chars) memberCount number ✅ Member count (positive number) avatar string/Buffer ✅ User avatar URL or buffer background string/Buffer ✅ Background image URL or buffer
Returns: Promise (PNG format)
wlc3(username, avatar)
Simple welcome image with avatar
Parameter Type Required Description username string ✅ Username to display (max 25 chars) avatar string/Buffer ✅ User avatar URL or buffer
Returns: Promise (PNG format)
wlc4(avatar, background, description)
Canvafy-powered welcome image
Parameter Type Required Description avatar string/Buffer ✅ User avatar URL or buffer background string/Buffer ✅ Background image URL or buffer description string ✅ Welcome message description
Returns: Promise (PNG format)
wlc5(username, guildName, memberCount, avatar, background, quality?)
Modern stylized welcome image
Parameter Type Required Description username string ✅ Username to display (max 25 chars) guildName string ✅ Guild/server name (max 30 chars) memberCount number ✅ Member count (positive number) avatar string/Buffer ✅ User avatar URL or buffer background string/Buffer ✅ Background image URL or buffer quality number ❌ JPEG quality 1-100 (default: 100)
Returns: Promise
Goodbye Images (gdb1 - gdb5)
gdb1(username, guildName, memberCount, avatar, background, quality?)
Stylized goodbye image
Parameter Type Required Description username string ✅ Username to display (max 25 chars) guildName string ✅ Guild/server name (max 30 chars) memberCount number ✅ Member count (positive number) avatar string/Buffer ✅ User avatar URL or buffer background string/Buffer ✅ Background image URL or buffer quality number ❌ JPEG quality 1-100 (default: 100)
Returns: Promise
gdb2(username, guildName, memberCount, avatar, background)
Goodbye image with rotated frame design
Parameter Type Required Description username string ✅ Username to display (max 25 chars) guildName string ✅ Guild/server name (max 50 chars) memberCount number ✅ Member count (positive number) avatar string/Buffer ✅ User avatar URL or buffer background string/Buffer ✅ Background image URL or buffer
Returns: Promise (PNG format)
gdb3(username, avatar)
Simple goodbye image with avatar
Parameter Type Required Description username string ✅ Username to display (max 25 chars) avatar string/Buffer ✅ User avatar URL or buffer
Returns: Promise (PNG format)
gdb4(avatar, background, description)
Canvafy-powered goodbye image
Parameter Type Required Description avatar string/Buffer ✅ User avatar URL or buffer background string/Buffer ✅ Background image URL or buffer description string ✅ Goodbye message description
Returns: Promise (PNG format)
gdb5(username, guildName, memberCount, avatar, background, quality?)
Modern stylized goodbye image
Parameter Type Required Description username string ✅ Username to display (max 25 chars) guildName string ✅ Guild/server name (max 30 chars) memberCount number ✅ Member count (positive number) avatar string/Buffer ✅ User avatar URL or buffer background string/Buffer ✅ Background image URL or buffer quality number ❌ JPEG quality 1-100 (default: 100)
Returns: Promise
💡 Examples
Example 1: Discord Bot Welcome Message
const { wlc5 } = require('phantom-canva');
const { MessageAttachment } = require('discord.js');
client.on('guildMemberAdd', async (member) => {
try {
const welcomeBuffer = await wlc5(
member.user.username,
member.guild.name,
member.guild.memberCount,
member.user.displayAvatarURL({ format: 'png', size: 256 }),
'https://example.com/welcome-bg.jpg',
90
);
const attachment = new MessageAttachment(welcomeBuffer, 'welcome.png');
const channel = member.guild.channels.cache.find(ch => ch.name === 'welcome');
if (channel) {
await channel.send({ content: `Welcome ${member.user}!`, files: [attachment] });
}
} catch (error) {
console.error('Error generating welcome image:', error);
}
});Example 2: Express API Endpoint
const express = require('express');
const { wlc4, gdb4 } = require('phantom-canva');
const app = express();
app.get('/api/welcome', async (req, res) => {
const { username, avatar, background, description } = req.query;
try {
const imageBuffer = await wlc4(avatar, background, description);
res.setHeader('Content-Type', 'image/png');
res.setHeader('Content-Disposition', 'inline; filename="welcome.png"');
res.send(imageBuffer);
} catch (error) {
res.status(500).json({ error: error.message });
}
});
app.get('/api/goodbye', async (req, res) => {
const { username, guildName, memberCount, avatar, background } = req.query;
try {
const imageBuffer = await gdb5(
username,
guildName,
parseInt(memberCount),
avatar,
background,
85
);
res.setHeader('Content-Type', 'image/jpeg');
res.send(imageBuffer);
} catch (error) {
res.status(500).json({ error: error.message });
}
});
app.listen(3000, () => console.log('Server running on port 3000'));Example 3: File Upload Support
const express = require('express');
const multer = require('multer');
const { wlc2, gdb2 } = require('phantom-canva');
const upload = multer({ storage: multer.memoryStorage() });
const app = express();
app.post('/api/welcome/upload', upload.fields([
{ name: 'avatar', maxCount: 1 },
{ name: 'background', maxCount: 1 }
]), async (req, res) => {
const { username, guildName, memberCount } = req.body;
const avatarBuffer = req.files['avatar'][0].buffer;
const backgroundBuffer = req.files['background'][0].buffer;
try {
const imageBuffer = await wlc2(
username,
guildName,
parseInt(memberCount),
avatarBuffer,
backgroundBuffer
);
res.setHeader('Content-Type', 'image/png');
res.send(imageBuffer);
} catch (error) {
res.status(500).json({ error: error.message });
}
});
app.post('/api/goodbye/upload', upload.fields([
{ name: 'avatar', maxCount: 1 },
{ name: 'background', maxCount: 1 }
]), async (req, res) => {
const { username, guildName, memberCount } = req.body;
const avatarBuffer = req.files['avatar'][0].buffer;
const backgroundBuffer = req.files['background'][0].buffer;
try {
const imageBuffer = await gdb2(
username,
guildName,
parseInt(memberCount),
avatarBuffer,
backgroundBuffer
);
res.setHeader('Content-Type', 'image/png');
res.send(imageBuffer);
} catch (error) {
res.status(500).json({ error: error.message });
}
});Example 4: Save to File
const fs = require('fs').promises;
const { wlc3, gdb3 } = require('phantom-canva');
async function saveImages() {
// Generate welcome image
const welcomeBuffer = await wlc3('NewMember', 'https://example.com/avatar.jpg');
await fs.writeFile('./output/welcome.png', welcomeBuffer);
// Generate goodbye image
const goodbyeBuffer = await gdb3('LeavingMember', 'https://example.com/avatar.jpg');
await fs.writeFile('./output/goodbye.png', goodbyeBuffer);
console.log('Images saved successfully!');
}
saveImages().catch(console.error);Example 5: Batch Generation
const { wlc1 } = require('phantom-canva');
async function generateBatchWelcome(users, guildInfo) {
const promises = users.map(user =>
wlc1(
user.username,
guildInfo.name,
guildInfo.icon,
guildInfo.memberCount,
user.avatar,
guildInfo.background,
80
)
);
const images = await Promise.all(promises);
return images.map((buffer, index) => ({
user: users[index].username,
image: buffer
}));
}
// Usage
const users = [
{ username: 'Alice', avatar: 'https://example.com/alice.jpg' },
{ username: 'Bob', avatar: 'https://example.com/bob.jpg' }
];
const guildInfo = {
name: 'Gaming Hub',
icon: 'https://example.com/guild-icon.jpg',
memberCount: 500,
background: 'https://example.com/bg.jpg'
};
const results = await generateBatchWelcome(users, guildInfo);
results.forEach(result => {
console.log(`Generated welcome for ${result.user}`);
// Save or send result.image
});🎨 Image Style Comparison
Version Style Format Features wlc1/gdb1 Stylized JPEG Circular avatar, guild icon, member count wlc2/gdb2 Rotated Frame PNG 17° rotated avatar, frame overlay wlc3/gdb3 Simple PNG Basic layout, centered avatar wlc4/gdb4 Canvafy PNG Modern design, customizable description wlc5/gdb5 Modern Stylized JPEG Large circular avatar, dynamic text sizing
🔧 Error Handling
const { wlc5, isValidImageUrl } = require('phantom-canva');
async function safeGenerateWelcome(params) {
// Validate inputs
if (!isValidImageUrl(params.avatar)) {
throw new Error('Invalid avatar URL');
}
if (params.username.length > 25) {
throw new Error('Username too long (max 25 characters)');
}
if (params.memberCount < 0) {
throw new Error('Member count must be positive');
}
try {
const imageBuffer = await wlc5(
params.username,
params.guildName,
params.memberCount,
params.avatar,
params.background,
params.quality || 90
);
return { success: true, image: imageBuffer };
} catch (error) {
console.error('Image generation failed:', error);
return { success: false, error: error.message };
}
}📝 Requirements
· Node.js: >= 16.0.0 · Dependencies: · canvas - Graphics rendering · @putuofc/assetsku - Font and frame assets · canvafy - Alternative rendering engine · axios - HTTP requests for images · file-type - Image type validation
🤝 Contributing
Contributions are welcome! Please follow these steps:
- Fork the repository
- Create a feature branch (git checkout -b feature/amazing)
- Commit changes (git commit -m 'Add amazing feature')
- Push to branch (git push origin feature/amazing)
- Open a Pull Request
📄 License
MIT © Phantom
🙏 Support
· 📧 Email: [email protected] · 🐛 Issues: GitHub Issues · 📖 Documentation: https://docs.phantom-canva.com
⚡ Quick Function Reference
// Welcome Images
import {
wlc1, wlc1FromFile,
wlc2, wlc2FromFile,
wlc3, wlc3FromFile,
wlc4, wlc4FromFile,
wlc5, wlc5FromFile
} from 'phantom-canva';
// Goodbye Images
import {
gdb1, gdb1FromFile,
gdb2, gdb2FromFile,
gdb3, gdb3FromFile,
gdb4, gdb4FromFile,
gdb5, gdb5FromFile
} from 'phantom-canva';Made with ❤️ for the developer community
Report Bug · Request Feature
