UNPKG

captcha-canvas

Version:

A captcha generator by using skia-canvas module.

460 lines (459 loc) 15 kB
import { Image } from "skia-canvas"; import { SetCaptchaOption, SetDecoyOption, SetTraceOption } from "./constants"; /** * Advanced CAPTCHA generator class with fluent API for creating highly customizable CAPTCHAs. * * This class provides a builder pattern interface for generating secure CAPTCHA images * with extensive customization options including text styling, background images, * trace lines, and decoy characters for enhanced security. * * @example Basic usage * ```typescript * const captcha = new CaptchaGenerator() * .setDimension(300, 100) * .setCaptcha({ text: 'HELLO', size: 50 }); * * const buffer = await captcha.generate(); * console.log('Generated text:', captcha.text); * ``` * * @example Advanced customization * ```typescript * const captcha = new CaptchaGenerator({ width: 400, height: 150 }) * .setCaptcha({ * text: 'SECURE', * size: 60, * colors: ['#ff6b6b', '#4ecdc4', '#45b7d1'], * rotate: 15, * skew: true * }) * .setTrace({ color: '#95a5a6', size: 3, opacity: 0.7 }) * .setDecoy({ total: 50, opacity: 0.4 }) * .setBackground('./background.jpg'); * * const buffer = await captcha.generate(); * ``` * * @since 2.0.0 */ export declare class CaptchaGenerator { private height; private width; private captcha; private trace; private decoy; private background?; /** * Creates a new CaptchaGenerator instance with specified dimensions. * * Initializes the generator with default settings and random text generation. * All configuration methods can be chained after construction for fluent API usage. * * @param options - Configuration options for the CAPTCHA generator * @param options.height - Height of the CAPTCHA image in pixels (default: 100) * @param options.width - Width of the CAPTCHA image in pixels (default: 300) * * @example Basic initialization * ```typescript * const captcha = new CaptchaGenerator(); * // Creates 300x100 CAPTCHA with default settings * ``` * * @example Custom dimensions * ```typescript * const captcha = new CaptchaGenerator({ height: 200, width: 600 }); * // Creates 600x200 CAPTCHA * ``` * * @since 2.0.0 */ constructor(options?: { height: number; width: number; }); /** * Gets the current CAPTCHA text that will be displayed in the image. * * This property returns the text that users need to enter to solve the CAPTCHA. * For array-based captchas with multiple text segments, it returns the concatenated result. * * @returns The complete CAPTCHA text string * * @example * ```typescript * const captcha = new CaptchaGenerator() * .setCaptcha({ text: 'HELLO' }); * * console.log(captcha.text); // Output: "HELLO" * ``` * * @example Array-based captcha * ```typescript * const captcha = new CaptchaGenerator() * .setCaptcha([ * { text: 'HE', color: '#ff0000' }, * { text: 'LLO', color: '#00ff00' } * ]); * * console.log(captcha.text); // Output: "HELLO" * ``` * * @since 2.0.3 */ get text(): string; /** * Sets the dimensions of the CAPTCHA image. * * This method allows you to customize the width and height of the generated CAPTCHA image. * Larger dimensions provide more space for text and security features but result in larger file sizes. * * @param height - Height of the CAPTCHA image in pixels * @param width - Width of the CAPTCHA image in pixels * @returns The CaptchaGenerator instance for method chaining * * @example Standard web form size * ```typescript * const captcha = new CaptchaGenerator() * .setDimension(150, 400); * ``` * * @example Large size for better readability * ```typescript * const captcha = new CaptchaGenerator() * .setDimension(200, 600) * .setCaptcha({ size: 80 }); // Larger text for larger canvas * ``` * * @example Mobile-friendly dimensions * ```typescript * const captcha = new CaptchaGenerator() * .setDimension(100, 250); * ``` * * @since 2.0.0 */ setDimension(height: number, width: number): CaptchaGenerator; /** * Sets a background image for the CAPTCHA to increase visual complexity and security. * * Background images make it significantly harder for OCR systems to automatically * solve the CAPTCHA while maintaining human readability. The image will be scaled * to fit the CAPTCHA dimensions. * * @param image - Image source as file path, URL, or Buffer * @returns The CaptchaGenerator instance for method chaining * * @example Using a local file path * ```typescript * const captcha = new CaptchaGenerator() * .setBackground('./assets/noise-pattern.jpg') * .setCaptcha({ opacity: 0.9 }); // Make text more visible over background * ``` * * @example Using a URL * ```typescript * const captcha = new CaptchaGenerator() * .setBackground('https://example.com/background.png'); * ``` * * @example Using a Buffer * ```typescript * import fs from 'fs'; * * const imageBuffer = fs.readFileSync('./background.jpg'); * const captcha = new CaptchaGenerator() * .setBackground(imageBuffer); * ``` * * @since 2.0.0 */ setBackground(image: string | Buffer): this; /** * Configures the CAPTCHA text appearance and content. * * This method allows extensive customization of the CAPTCHA text including font, * size, colors, rotation, skewing, and the actual text content. Supports both * single configuration objects and arrays for multi-styled text segments. * * @param option - Single captcha configuration or array of configurations for multi-styled text * @returns The CaptchaGenerator instance for method chaining * * @example Basic text customization * ```typescript * const captcha = new CaptchaGenerator() * .setCaptcha({ * text: 'SECURE', * font: 'Arial', * size: 60, * color: '#2c3e50' * }); * ``` * * @example Advanced styling with rotation and skewing * ```typescript * const captcha = new CaptchaGenerator() * .setCaptcha({ * text: 'VERIFY', * size: 50, * rotate: 20, // Random rotation up to ±20 degrees * skew: true, // Apply random skewing * opacity: 0.8 // Semi-transparent text * }); * ``` * * @example Multi-color text using colors array * ```typescript * const captcha = new CaptchaGenerator() * .setCaptcha({ * text: 'RAINBOW', * size: 45, * colors: ['#e74c3c', '#f39c12', '#f1c40f', '#27ae60', '#3498db', '#9b59b6'] * }); * ``` * * @example Multi-styled text segments * ```typescript * const captcha = new CaptchaGenerator() * .setCaptcha([ * { text: 'SEC', size: 50, color: '#e74c3c', font: 'Arial' }, * { text: 'URE', size: 45, color: '#27ae60', font: 'Times' } * ]); * ``` * * @example Random text generation * ```typescript * const captcha = new CaptchaGenerator() * .setCaptcha({ * characters: 8, // Generate 8 random characters * size: 40, * colors: ['#34495e', '#e67e22'] * }); * ``` * * @since 2.0.0 */ setCaptcha(option: SetCaptchaOption | SetCaptchaOption[]): this; /** * Configures trace lines that connect CAPTCHA characters for enhanced security. * * Trace lines are drawn connecting the CAPTCHA characters, making it significantly * harder for automated systems to segment and recognize individual characters while * maintaining human readability. * * @param option - Trace line appearance configuration * @returns The CaptchaGenerator instance for method chaining * * @example Basic trace line * ```typescript * const captcha = new CaptchaGenerator() * .setCaptcha({ text: 'HELLO' }) * .setTrace({ color: '#95a5a6', size: 3 }); * ``` * * @example Subtle trace for better readability * ```typescript * const captcha = new CaptchaGenerator() * .setCaptcha({ text: 'VERIFY' }) * .setTrace({ * color: '#bdc3c7', * size: 2, * opacity: 0.6 // Semi-transparent trace * }); * ``` * * @example Bold security trace * ```typescript * const captcha = new CaptchaGenerator() * .setCaptcha({ text: 'SECURE' }) * .setTrace({ * color: '#e74c3c', * size: 5, * opacity: 0.8 * }); * ``` * * @example Disable trace lines * ```typescript * const captcha = new CaptchaGenerator() * .setCaptcha({ text: 'CLEAN' }) * .setTrace({ opacity: 0 }); // Completely transparent = disabled * ``` * * @since 2.0.0 */ setTrace(option: SetTraceOption): this; /** * Configures decoy characters that add visual noise to prevent automated solving. * * Decoy characters are randomly placed fake characters that confuse OCR systems * while being distinguishable from the actual CAPTCHA text by humans through * differences in opacity, size, or color. * * @param option - Decoy characters configuration * @returns The CaptchaGenerator instance for method chaining * * @example Basic decoy setup * ```typescript * const captcha = new CaptchaGenerator() * .setCaptcha({ text: 'HELLO' }) * .setDecoy({ * total: 30, * opacity: 0.3, * color: '#95a5a6' * }); * ``` * * @example Subtle decoys for clean look * ```typescript * const captcha = new CaptchaGenerator() * .setCaptcha({ text: 'VERIFY' }) * .setDecoy({ * total: 15, * size: 12, * opacity: 0.2, * font: 'Arial' * }); * ``` * * @example Heavy security with many decoys * ```typescript * const captcha = new CaptchaGenerator() * .setCaptcha({ text: 'SECURE' }) * .setDecoy({ * total: 50, * size: 18, * opacity: 0.4, * color: '#7f8c8d' * }); * ``` * * @example Disable decoy characters * ```typescript * const captcha = new CaptchaGenerator() * .setCaptcha({ text: 'SIMPLE' }) * .setDecoy({ opacity: 0 }); // No decoy characters * ``` * * @since 2.0.0 */ setDecoy(option: SetDecoyOption): this; /** * Generates the final CAPTCHA image as a PNG buffer asynchronously. * * This method renders all configured elements (background, decoys, text, traces) * into a final PNG image buffer that can be saved to file or sent to clients. * The generation process is asynchronous to handle background image loading. * * @returns Promise that resolves to a PNG image buffer * * @example Basic generation and file saving * ```typescript * import fs from 'fs'; * * const captcha = new CaptchaGenerator() * .setCaptcha({ text: 'HELLO' }); * * const buffer = await captcha.generate(); * fs.writeFileSync('captcha.png', buffer); * console.log('CAPTCHA text:', captcha.text); * ``` * * @example Web server response * ```typescript * import express from 'express'; * * app.get('/captcha', async (req, res) => { * const captcha = new CaptchaGenerator() * .setDimension(300, 100) * .setCaptcha({ characters: 6 }); * * const buffer = await captcha.generate(); * * // Store captcha.text in session for verification * req.session.captcha = captcha.text; * * res.type('png').send(buffer); * }); * ``` * * @example Complete customization * ```typescript * const captcha = new CaptchaGenerator({ width: 400, height: 150 }) * .setBackground('./noise-bg.jpg') * .setCaptcha({ * text: 'SECURE', * size: 60, * colors: ['#e74c3c', '#3498db'], * rotate: 15 * }) * .setTrace({ color: '#95a5a6', size: 3 }) * .setDecoy({ total: 40, opacity: 0.3 }); * * const buffer = await captcha.generate(); * ``` * * @throws {Error} When background image fails to load or other rendering errors occur * * @since 2.0.0 */ generate(): Promise<Buffer>; /** * Generates the CAPTCHA image synchronously without async/await. * * This method provides synchronous CAPTCHA generation for use cases where * async operations are not suitable. Note that background images set via * `setBackground()` are ignored - use the `background` parameter instead. * * @param option - Additional options for synchronous generation * @param option.background - Pre-loaded background image (use `resolveImage()` to load) * @returns PNG image buffer * * @example Basic synchronous generation * ```typescript * const captcha = new CaptchaGenerator() * .setCaptcha({ text: 'SYNC' }); * * const buffer = captcha.generateSync(); * fs.writeFileSync('captcha.png', buffer); * ``` * * @example With pre-loaded background image * ```typescript * import { CaptchaGenerator, resolveImage } from 'captcha-canvas'; * * // Load background image first * const backgroundImage = await resolveImage('./background.jpg'); * * const captcha = new CaptchaGenerator() * .setCaptcha({ text: 'HELLO' }); * * // Generate synchronously with background * const buffer = captcha.generateSync({ background: backgroundImage }); * fs.writeFileSync('captcha.png', buffer); * ``` * * @example Synchronous generation in non-async context * ```typescript * function createCaptchaSync() { * const captcha = new CaptchaGenerator() * .setDimension(250, 80) * .setCaptcha({ characters: 5, size: 35 }) * .setTrace({ size: 2, opacity: 0.7 }); * * return { * buffer: captcha.generateSync(), * text: captcha.text * }; * } * ``` * * * **Note:** Background images set via `setBackground()` are not used in sync mode. * Use the `background` parameter with pre-loaded images instead. * * @since 2.2.0 */ generateSync(option?: { background?: Image; }): Buffer; }