Skip to main content
Glama
image.ts2.95 kB
/** * Image utility functions for saving and processing generated images. */ import { existsSync, statSync } from "fs"; import { mkdir, writeFile } from "fs/promises"; import { dirname, extname, join, resolve } from "path"; /** * Get file extension from MIME type. */ export function getExtensionFromMimeType(mimeType: string): string { const mimeToExt: Record<string, string> = { "image/png": ".png", "image/jpeg": ".jpg", "image/jpg": ".jpg", "image/webp": ".webp", "image/gif": ".gif", }; return mimeToExt[mimeType] ?? ".png"; } /** * Generate a default filename with timestamp. */ export function generateFilename(prefix: string = "image", mimeType: string = "image/png"): string { const timestamp = new Date().toISOString().replace(/[:.]/g, "-").slice(0, 19); const ext = getExtensionFromMimeType(mimeType); return `${prefix}-${timestamp}${ext}`; } /** * Sanitize a string to be safe for use as a filename. */ export function sanitizeFilename(name: string): string { return name .replace(/[^a-zA-Z0-9-_]/g, "-") // Replace unsafe chars with dash .replace(/-+/g, "-") // Collapse multiple dashes .replace(/^-|-$/g, "") // Remove leading/trailing dashes .toLowerCase() .slice(0, 100); // Limit length } /** * Save base64 image data to a file. * If outputPath is a directory, generates a filename automatically. */ export async function saveImage( base64Data: string, outputPath: string, mimeType: string = "image/png" ): Promise<string> { // Resolve to absolute path let absolutePath = resolve(outputPath); // Check if outputPath is an existing directory or ends with a path separator const isDirectory = outputPath.endsWith("/") || outputPath.endsWith("\\") || (existsSync(absolutePath) && statSync(absolutePath).isDirectory()); if (isDirectory) { // Generate a filename and append to the directory path const filename = generateFilename("blog-image", mimeType); absolutePath = join(absolutePath, filename); } // Ensure the directory exists const dir = dirname(absolutePath); if (!existsSync(dir)) { await mkdir(dir, { recursive: true }); } // Add extension if missing let finalPath = absolutePath; if (!extname(finalPath)) { finalPath += getExtensionFromMimeType(mimeType); } // Decode and write const buffer = Buffer.from(base64Data, "base64"); await writeFile(finalPath, buffer); return finalPath; } /** * Calculate approximate file size from base64 data. */ export function estimateFileSize(base64Data: string): number { // Base64 is ~4/3 the size of the original binary return Math.floor((base64Data.length * 3) / 4); } /** * Format file size for display. */ export function formatFileSize(bytes: number): string { if (bytes < 1024) return `${bytes} B`; if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`; return `${(bytes / (1024 * 1024)).toFixed(1)} MB`; }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/12-days-of-shipmas-2025/day-1-image-generation-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server