@irithell-js/image2braille
v1.0.0
Published
Convert images to Braille Unicode art with customizable themes, colors, and multiple output formats (console, TXT, HTML, PNG).
Downloads
38
Maintainers
Readme
image2braille
High-performance image to Braille Unicode art converter with Floyd-Steinberg dithering, 20+ built-in themes, and multiple output formats (console, TXT, HTML, PNG).
Features
- Multiple Output Formats - Console, TXT, HTML (interactive), PNG
- 20+ Built-in Themes - Dracula, Nord, Monokai, Solarized, Terminal styles
- Floyd-Steinberg Dithering - Smooth gradients with error diffusion algorithm
- Flexible Color System - Use hex codes, RGB values, or color names
- Quality Presets - Fast, balanced, or best quality processing
- Smart Resizing - Lanczos3, Mitchell, Cubic kernels with aspect ratio preservation
- TypeScript - Full type definitions included
- Dual Format - ESM and CommonJS support
- Zero Dependencies - Only Sharp for image processing
Installation
npm i @irithell-js/image2brailleQuick Start
Basic Usage (ESM)
import { Image2Braille } from "image2braille";
const converter = new Image2Braille();
// Convert and display in console
await converter.convertAndShow("photo.jpg", { width: 80 });
// Convert and save as PNG
await converter.convertAndSave(
"photo.jpg",
"output.png",
{ width: 100 },
{ format: "image", theme: "dracula" },
);
// Get art as string
const art = await converter.convertToString("photo.jpg", { width: 60 });
console.log(art);Basic Usage (CommonJS)
const { Image2Braille } = require("image2braille");
async function convert() {
const converter = new Image2Braille();
await converter.convertAndShow("image.png", { width: 80 });
}
convert();Using Themes
// Use built-in theme
const converter = new Image2Braille({
theme: "nord",
dithering: true,
quality: "best",
});
// List all available themes
Image2Braille.listThemes();
// Output:
// Available themes:
// dark - Classic black and white
// bg: #000000 fg: #ffffff
// terminal - Matrix-style green phosphor
// bg: #000000 fg: #00ff00
// ...
// Get theme names programmatically
const themes = Image2Braille.getThemeNames();
// ['dark', 'light', 'terminal', 'dracula', 'nord', ...]Configuration
Constructor Options
const converter = new Image2Braille({
// Conversion settings
defaultWidth: 80, // Default output width in characters
defaultHeight: undefined, // Default height (auto if undefined)
preserveAspectRatio: true, // Maintain image proportions
threshold: 128, // Black/white threshold (0-255)
dithering: true, // Enable Floyd-Steinberg dithering
invert: false, // Invert colors (negative)
// Output settings
outputFormat: "console", // Default format: console|txt|html|image
outputDir: "./output", // Output directory
// Style settings
theme: "dark", // Theme name (overrides colors)
fontSize: 10, // Font size for HTML/PNG output
fontFamily: "Cascadia Code, Courier New, monospace",
backgroundColor: "#000000", // Background color (hex, rgb, or name)
textColor: "#ffffff", // Text color (hex, rgb, or name)
lineHeight: 1.0, // Line spacing
padding: 20, // Padding for HTML/PNG
// Quality settings
resizeKernel: "lanczos3", // Resize algorithm
quality: "balanced", // Processing speed: fast|balanced|best
// Logging
logger: console, // Optional logger instance
});Quality Presets
// Ultra-fast (nearest neighbor, no dithering)
const fast = new Image2Braille({
quality: "fast",
resizeKernel: "nearest",
dithering: false,
});
// Balanced (recommended)
const balanced = new Image2Braille({
quality: "balanced",
resizeKernel: "lanczos3",
dithering: true,
});
// Best quality (slowest, highest detail)
const best = new Image2Braille({
quality: "best",
resizeKernel: "lanczos3",
dithering: true,
});Color Configuration
// Using hex colors
const hex = new Image2Braille({
backgroundColor: "#282a36",
textColor: "#f8f8f2",
});
// Using RGB
const rgb = new Image2Braille({
backgroundColor: "rgb(40, 42, 54)",
textColor: "rgb(248, 248, 242)",
});
// Using color names
const named = new Image2Braille({
backgroundColor: "black",
textColor: "green",
});
// Supported color names:
// black, white, red, green, blue, yellow, cyan, magenta, orange,
// purple, pink, lime, teal, navy, maroon, olive, gray, darkgray,
// lightgray, silver, darkred, darkgreen, darkblue, lightred,
// lightgreen, lightblue, transparentAPI Reference
Image2Braille Methods
convert(input: string | Buffer, options?: ConversionOptions): Promise<ConversionResult>
Convert an image to Braille art.
const result = await converter.convert("photo.jpg", {
width: 100, // Width in characters
height: 50, // Height in characters (optional)
threshold: 128, // Black/white threshold (0-255)
dithering: true, // Enable dithering
invert: false, // Invert colors
aspectRatio: true, // Preserve aspect ratio
});
console.log(result.art); // Braille art string
console.log(result.width); // 100 characters
console.log(result.height); // 50 characters
console.log(result.originalWidth); // 1920 pixels
console.log(result.originalHeight); // 1080 pixels
console.log(result.processingTime); // 234 msconvertAndSave(input, outputPath?, conversionOptions?, saveOptions?): Promise<ConversionResult>
Convert and save to file.
// Save as PNG with theme
await converter.convertAndSave(
"input.jpg",
"output.png",
{ width: 80 },
{
format: "image",
theme: "dracula",
fontSize: 12,
},
);
// Save as HTML with custom colors
await converter.convertAndSave(
"input.jpg",
"output.html",
{ width: 100, dithering: true },
{
format: "html",
backgroundColor: "navy",
textColor: "cyan",
},
);
// Save as TXT
await converter.convertAndSave(
"input.jpg",
"output.txt",
{ width: 60 },
{ format: "txt" },
);
// Display in console
await converter.convertAndSave(
"input.jpg",
undefined,
{ width: 80 },
{ format: "console", showInfo: true },
);convertToString(input, options?): Promise<string>
Convert and return art as string.
const art = await converter.convertToString("photo.jpg", { width: 60 });
console.log(art);convertAndShow(input, options?): Promise<ConversionResult>
Convert and display in console with metadata.
await converter.convertAndShow("photo.jpg", { width: 80 });
// Output:
// Original: 1920x1080px
// Braille: 80x33 characters
// Represented pixels: 160x132px
//
// ⣿⣿⣿⣿⣿⣿...updateConfig(newConfig: Partial<Image2BrailleConfig>): void
Update configuration at runtime.
converter.updateConfig({
theme: "terminal",
dithering: false,
threshold: 150,
});getConfig(): Image2BrailleConfig
Get current configuration.
const config = converter.getConfig();
console.log(config.theme);
console.log(config.threshold);static listThemes(): void
List all available themes.
Image2Braille.listThemes();static getThemeNames(): string[]
Get array of theme names.
const themes = Image2Braille.getThemeNames();
// ['dark', 'light', 'terminal', ...]Available Themes
| Theme | Description | Background | Foreground |
| ----------------- | ---------------------------- | ---------- | ---------- |
| dark | Classic black and white | #000000 | #ffffff |
| light | White background, black text | #ffffff | #000000 |
| terminal | Matrix-style green phosphor | #000000 | #00ff00 |
| amber | Retro DOS amber | #1a0f00 | #ffb000 |
| green | Classic green terminal | #0a1a0a | #00ff41 |
| dracula | Dracula theme | #282a36 | #f8f8f2 |
| monokai | Monokai theme | #272822 | #f8f8f2 |
| solarized-dark | Solarized dark | #002b36 | #839496 |
| solarized-light | Solarized light | #fdf6e3 | #657b83 |
| nord | Nord theme | #2e3440 | #d8dee9 |
| one-dark | Atom One Dark | #282c34 | #abb2bf |
| gruvbox-dark | Gruvbox dark | #282828 | #ebdbb2 |
| gruvbox-light | Gruvbox light | #fbf1c7 | #3c3836 |
| blue | Cyberpunk blue | #001122 | #00aaff |
| purple | Neon purple | #0d001a | #bf40ff |
| red | Alert red | #1a0000 | #ff4444 |
| cyan | Bright cyan | #001a1a | #00ffff |
| paper | Aged paper | #f5f5dc | #2c2c2c |
| hacker | Hacker terminal | #0c0c0c | #0f0 |
Advanced Usage
Batch Processing with Multiple Themes
const converter = new Image2Braille({
outputDir: "./output",
});
const themes = ["dark", "terminal", "dracula", "nord"];
for (const theme of themes) {
converter.updateConfig({ theme });
await converter.convertAndSave(
"photo.jpg",
`./output/${theme}.png`,
{ width: 80 },
{ format: "image" },
);
}Custom Pipeline
import { Image2Braille } from "image2braille";
import { readFileSync } from "fs";
// Load image as buffer
const buffer = readFileSync("photo.jpg");
// Convert with custom settings
const converter = new Image2Braille({
dithering: false,
threshold: 150,
});
const result = await converter.convert(buffer, {
width: 100,
invert: true,
});
// Process the art string
const lines = result.art.split("\n");
console.log(`Generated ${lines.length} lines`);Error Handling
try {
const result = await converter.convert("invalid.jpg");
} catch (error) {
if (error.message.includes("missing dimensions")) {
console.error("Invalid image file");
} else {
console.error("Conversion failed:", error.message);
}
}Performance Monitoring
const start = Date.now();
const result = await converter.convert("large-photo.jpg", { width: 200 });
console.log(`Processing took ${result.processingTime}ms`);
console.log(`Total time: ${Date.now() - start}ms`);Output Formats
Console
Displays art directly in terminal with metadata.
TXT
Plain text file with Braille characters (UTF-8 encoded).
HTML
Interactive HTML with:
- All themes as clickable buttons
- Copy to clipboard
- Download as TXT
- Smooth theme transitions
- Responsive design
PNG
Rendered image with:
- Anti-aliased text
- Custom fonts
- Configurable size and padding
- High-quality SVG-to-PNG conversion
Performance
Conversion speed depends on image size, quality settings, and dithering:
| Image Size | Width | Quality | Dithering | Time | | ---------- | ----- | -------- | --------- | ------ | | 1920x1080 | 80 | fast | off | ~50ms | | 1920x1080 | 80 | balanced | on | ~90ms | | 1920x1080 | 150 | best | on | ~175ms | | 3840x2160 | 80 | balanced | on | ~140ms | | 3840x2160 | 200 | best | on | ~400ms |
Times measured on local tests
How It Works
- Load Image - Uses Sharp to read image file or buffer
- Calculate Dimensions - Determines target size preserving aspect ratio
- Resize - Resizes to exact pixel dimensions (width×2, height×4)
- Convert to Grayscale - Calculates luminance using ITU-R BT.709 formula
- Apply Dithering - Floyd-Steinberg error diffusion (optional)
- Map to Braille - Converts 2×4 pixel blocks to Braille Unicode (U+2800-U+28FF)
- Output - Renders to selected format
Braille Unicode
Each Braille character represents a 2×4 pixel block:
⠁ = pixel at (0,0)
⠂ = pixel at (0,1)
⠄ = pixel at (0,2)
⡀ = pixel at (0,3)
⠈ = pixel at (1,0)
⠐ = pixel at (1,1)
⠠ = pixel at (1,2)
⢀ = pixel at (1,3)Example: ⣿ = all 8 pixels filled (U+28FF)
Requirements
- Node.js >= 18.0.0
- Sharp (automatically installed)
License
MIT
Changelog
1.0.0 (Latest)
- Initial release
- Floyd-Steinberg dithering support
- 20+ built-in themes
- Multiple output formats (console, TXT, HTML, PNG)
- Color name resolution (hex, rgb, names)
- Quality presets (fast, balanced, best)
- Multiple resize kernels (nearest, cubic, mitchell, lanczos2, lanczos3)
- Aspect ratio preservation
- TypeScript support with full type definitions
- ESM and CommonJS support
