image-to-anything
v0.0.13
Published
A standalone React TypeScript component that converts images to ASCII, dithered, and other visual representations
Maintainers
Readme
ImageToAnything
A high-performance, standalone React TypeScript component that converts images to ASCII art, dithered images, and other visual representations with zero external dependencies.
Features
- Multiple Conversion Modes: ASCII art, dithered images, RGB/CMYK rasterization, pixelate, edge detection, halftone, posterize, stipple, and more
- Zero Dependencies: All image processing implemented from scratch using Canvas API
- TypeScript First: Full type safety with exported
.d.tsfiles - High Performance: Web Workers, LRU caching, and optimized algorithms
- Customizable: Extensive options for colors, filters, and visual effects
- Interactive: Full event handler support and real-time manipulation
- Flexible Output: Canvas, Base64, HTML, and SVG formats for all modes
- Vector Dithering: HTML and SVG output for dithered images with scalable quality
- ASCII Image Export: Direct base64 image export with high-quality font rendering
- Animation Support: Built-in movement and animation system
- Export Functionality: Export to JPG, PNG, or SVG with one method call
- Viewport System: Control ASCII character grid independently of display size
Installation
npm install image-to-anythingyarn add image-to-anythingpnpm add image-to-anythingQuick Start
import { ImageToAnything } from 'image-to-anything';
function App() {
return (
<ImageToAnything
src="https://example.com/image.jpg"
mode="ascii"
onConvert={(result) => console.log('Converted!', result)}
/>
);
}API Reference
Props
Required Props
| Prop | Type | Description |
|------|------|-------------|
| src | string | Image source URL or base64 data URI (supports jpg, png, svg, gif, webp) |
| mode | 'ascii' \| 'dithered' \| 'rgb-raster' \| 'cmyk-raster' \| 'pixelate' \| 'edges' \| 'halftone' \| 'posterize' \| 'stipple' | Conversion mode |
Optional Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| options | ConversionOptions | {} | Conversion configuration options |
| onConvert | (result: ConversionResult) => void | - | Callback when conversion completes |
| onError | (error: Error) => void | - | Callback when an error occurs |
| onProgress | (event: ProgressEvent) => void | - | Callback for conversion progress updates |
| onClick | (event: React.MouseEvent) => void | - | Click event handler |
| onDoubleClick | (event: React.MouseEvent) => void | - | Double click event handler |
| onMouseOver | (event: React.MouseEvent) => void | - | Mouse over event handler |
| onMouseOut | (event: React.MouseEvent) => void | - | Mouse out event handler |
| onDragStart | (event: React.DragEvent) => void | - | Drag start event handler |
| onDragEnd | (event: React.DragEvent) => void | - | Drag end event handler |
| onDragOver | (event: React.DragEvent) => void | - | Drag over event handler |
| onDragLeave | (event: React.DragEvent) => void | - | Drag leave event handler |
| onDrop | (event: React.DragEvent) => void | - | Drop event handler |
| width | number \| string | - | Image width (like img tag) |
| height | number \| string | - | Image height (like img tag) |
| alt | string | - | Alt text for accessibility |
| className | string | - | CSS class name |
| style | React.CSSProperties | - | Inline styles |
ConversionOptions
interface ConversionOptions {
quality?: number; // 0-100, default: 100
color?: ColorOptions;
ascii?: AsciiOptions;
dithered?: DitheredOptions;
rgbRaster?: RGBRasterOptions;
cmykRaster?: CMYKRasterOptions;
halftone?: HalftoneOptions;
edges?: EdgesOptions;
pixelate?: PixelateOptions;
posterize?: PosterizeOptions;
stipple?: StippleOptions;
format?: OutputFormat; // 'canvas' | 'base64' | 'html' | 'svg'
filters?: FilterOptions;
movement?: MovementOptions;
}ColorOptions
interface ColorOptions {
backgroundColor?: string; // CSS color, supports transparent
palette?: string[]; // Array of hex colors for dithering
}AsciiOptions
interface AsciiOptions {
allowedCharacters?: string; // Custom character set (default: " .:-=+*#%@")
blacklistedCharacters?: string; // Characters to exclude
letterClassName?: string; // CSS class for individual letters
font?: {
family?: string; // Font family (default: 'monospace')
weight?: string; // Font weight (default: 'normal')
style?: string; // Font style (default: 'normal')
};
colorPalette?: number; // Color quantization level (default: 1)
viewport?: {
columns?: number; // Number of characters per row
rows?: number; // Number of character rows
autoCalculate?: boolean; // Auto-calculate from aspect ratio
};
dynamicFontWeight?: boolean; // Enable dynamic font-weight based on brightness
randomization?: number; // 0-1, randomness factor for character selection
}DitheredOptions
interface DitheredOptions {
algorithm?: 'floyd-steinberg' | 'atkinson' | 'bayer';
dotSize?: number; // 1-10, default: 1
dotBaseColor?: string; // Hex color
dotShape?: ReactNode; // Custom SVG shape element
dotClassName?: string; // CSS class for individual dots
}RGBRasterOptions
interface RGBRasterOptions {
layout?: 'split' | 'overlay' | 'separate';
channels?: ('r' | 'g' | 'b')[];
intensityMap?: boolean;
gridLines?: boolean;
gridColor?: string;
dotMode?: 'none' | 'halftone' | 'inverse' | 'variable';
baseDotSize?: number;
dotSizeVariation?: number;
dotShape?: 'circle' | 'square' | 'diamond';
dotSpacing?: number;
}CMYKRasterOptions
interface CMYKRasterOptions {
layout?: 'split' | 'overlay' | 'separate';
channels?: ('c' | 'm' | 'y' | 'k')[];
halftone?: boolean;
halftoneSize?: number;
gridLines?: boolean;
gridColor?: string;
dotMode?: 'none' | 'halftone' | 'inverse' | 'variable';
baseDotSize?: number;
dotSizeVariation?: number;
dotShape?: 'circle' | 'square' | 'diamond';
dotSpacing?: number;
angleOffset?: boolean; // Authentic print simulation
}HalftoneOptions
interface HalftoneOptions {
dotSize?: number; // 2-20, default: 8
angle?: number; // 0-360, default: 45
shape?: 'circle' | 'square' | 'line';
backgroundColor?: string;
}EdgesOptions
interface EdgesOptions {
threshold?: number; // 0-255, default: 50
invert?: boolean; // default: false
lineColor?: string; // default: '#000000'
backgroundColor?: string; // default: '#ffffff'
}PixelateOptions
interface PixelateOptions {
blockSize?: number; // 2-50, default: 8
quantizeColors?: boolean; // default: false
colorLevels?: number; // 2-256, default: 16
}PosterizeOptions
interface PosterizeOptions {
levels?: number; // 2-255, default: 4
edgeDetection?: boolean; // default: false
edgeThickness?: number; // 1-10, default: 1
}StippleOptions
interface StippleOptions {
dotDensity?: number; // 0.1-2.0, default: 1.0
minDotSize?: number; // 1-10, default: 1
maxDotSize?: number; // 2-20, default: 8
dotShape?: 'circle' | 'square' | 'triangle';
colorMode?: 'full' | 'monochrome' | 'limited';
backgroundColor?: string;
}FilterOptions
interface FilterOptions {
brightness?: number; // 0-2, default: 1
contrast?: number; // 0-2, default: 1
saturation?: number; // 0-10, default: 1
hue?: number; // 0-360, default: 0
blur?: number; // 0-10, default: 0
}MovementOptions
interface MovementOptions {
enabled?: boolean; // default: false
speed?: number; // 0-10, default: 1
direction?: 'random' | 'left' | 'right' | 'up' | 'down';
}Conversion Modes
ImageToAnything supports 9 distinct conversion modes, each with unique visual characteristics and customization options:
ASCII Art
Converts images to text characters using brightness mapping. Supports custom character sets, fonts, colors, viewport control, dynamic font-weight, and character randomization.
Advanced ASCII Features
Dynamic Font Weight
The ASCII mode now supports dynamic font-weight mapping based on pixel brightness:
- Mapping Direction: Darker colors → heavier font weights (900), Lighter colors → lighter weights (100)
- Range: Full CSS font-weight spectrum (100-900)
- Visual Effect: Creates depth and emphasis in ASCII art
- Output Formats: Supported in HTML, SVG, Canvas, and Base64
// Enable dynamic font-weight
<ImageToAnything
src="image.jpg"
mode="ascii"
options={{
ascii: {
dynamicFontWeight: true,
colorPalette: 2, // Required for color-based weighting
}
}}
/>Character Randomization
Add artistic variation to ASCII output with controlled randomness:
- Range: 0-1 factor where 0 = exact behavior, 1 = maximum randomness
- Algorithm: Calculates ideal character based on brightness, applies random offset
- Visual Quality: Prioritized for artistic effect over performance
- Smart Randomization: Still considers color weight while adding variation
// Add controlled randomness
<ImageToAnything
src="image.jpg"
mode="ascii"
options={{
ascii: {
randomization: 0.5, // Medium randomness
dynamicFontWeight: true, // Combine for best effect
}
}}
/>Combining Features
For maximum artistic impact, combine both features with filters:
<ImageToAnything
src="image.jpg"
mode="ascii"
options={{
ascii: {
dynamicFontWeight: true,
randomization: 0.3,
colorPalette: 3,
viewport: { columns: 120, rows: 40 }
},
filters: {
contrast: 1.2, // Enhance brightness differences
brightness: 1.1,
}
}}
/>Dithered
Applies dithering algorithms (Floyd-Steinberg, Atkinson, Bayer) to create artistic dot patterns. Supports custom SVG shapes and vector output.
RGB Raster
Separates image into RGB color channels with various layout options. Advanced dot modes including halftone effects and grid visualization.
CMYK Raster
Print-simulation mode separating into CMYK channels. Authentic print reproduction with angle offset and professional dot patterns.
Pixelate
Creates mosaic/pixelation effects with configurable block sizes and optional color quantization.
Edge Detection
Extracts and highlights edges using configurable thresholds. Supports inversion and custom colors.
Halftone
Traditional printing halftone effect with configurable dot size, angle, and shapes (circle, square, line).
Posterize
Reduces color levels with optional edge detection for artistic posterization effects.
Stipple
Creates artistic stippling patterns with variable dot sizes, shapes, and color modes.
Usage Examples
ASCII Art Conversion
<ImageToAnything
src="https://example.com/photo.jpg"
mode="ascii"
options={{
ascii: {
allowedCharacters: " .:-=+*#%@",
},
format: "html",
color: {
backgroundColor: "#000000",
},
}}
/>ASCII with Dynamic Font Weight
<ImageToAnything
src="https://example.com/photo.jpg"
mode="ascii"
options={{
ascii: {
dynamicFontWeight: true, // Darker areas get bolder fonts
colorPalette: 2, // Enable color support
viewport: {
columns: 80, // Control character grid size
rows: 30,
},
},
format: "html",
}}
/>ASCII with Randomization
<ImageToAnything
src="https://example.com/photo.jpg"
mode="ascii"
options={{
ascii: {
randomization: 0.5, // 0 = exact, 1 = maximum randomness
dynamicFontWeight: true, // Combine with font-weight for artistic effect
allowedCharacters: " .:-=+*#%@AaBbCcDdEe",
},
format: "html",
}}
/>ASCII with All New Features
<ImageToAnything
src="https://example.com/photo.jpg"
mode="ascii"
options={{
ascii: {
dynamicFontWeight: true, // Enable brightness-based font weight
randomization: 0.3, // Add artistic randomness
allowedCharacters: " .:-=+*#%@",
colorPalette: 3, // More colors for better effect
font: {
family: "Courier New",
style: "italic",
},
viewport: {
columns: 100, // High resolution ASCII
autoCalculate: true,
},
},
format: "html",
filters: {
contrast: 1.2, // Enhance for better font-weight effect
brightness: 1.1,
},
}}
/>Dithered Image with Floyd-Steinberg
<ImageToAnything
src="https://example.com/photo.jpg"
mode="dithered"
options={{
dithered: {
algorithm: "floyd-steinberg",
dotSize: 2,
},
color: {
palette: ["#000000", "#ffffff"],
},
}}
/>Dithered as HTML/SVG
// HTML output with colored div grid
<ImageToAnything
src="https://example.com/photo.jpg"
mode="dithered"
options={{
format: "html",
dithered: {
algorithm: "atkinson",
dotSize: 3,
},
}}
/>
// SVG output with vector rectangles
<ImageToAnything
src="https://example.com/photo.jpg"
mode="dithered"
options={{
format: "svg",
dithered: {
algorithm: "bayer",
dotSize: 2,
dotShape: <circle cx="5" cy="5" r="4" />,
},
}}
/>Custom SVG Dither Shape
<ImageToAnything
src="https://example.com/photo.jpg"
mode="dithered"
options={{
dithered: {
algorithm: "atkinson",
dotSize: 3,
dotShape: <polygon points="5,0 10,5 5,10 0,5" />,
},
}}
/>ASCII with Viewport Control
<ImageToAnything
src="https://example.com/photo.jpg"
mode="ascii"
width={800}
height={600}
options={{
ascii: {
viewport: {
columns: 80, // 80 characters wide
rows: 24, // 24 characters tall
},
},
format: "html",
}}
/>ASCII as Base64 Image
// Export ASCII directly as rasterized image (JPG/PNG)
<ImageToAnything
src="https://example.com/photo.jpg"
mode="ascii"
options={{
format: "base64",
quality: 90,
ascii: {
viewport: { columns: 100, rows: 50 },
font: {
family: "Courier New",
weight: "bold",
},
},
}}
onConvert={(result) => {
// result.data is a base64 data URI
console.log(result.data);
}}
/>Export Functionality
import { useRef } from 'react';
import { ImageToAnything, ImageToAnythingRef } from 'image-to-anything';
function App() {
const imageRef = useRef<ImageToAnythingRef>(null);
const handleExportJPG = async () => {
const blob = await imageRef.current?.exportAsJPG(0.9);
// Use blob...
};
const handleDownload = async () => {
await imageRef.current?.download('png', 'my-image.png');
};
return (
<ImageToAnything
ref={imageRef}
src="https://example.com/photo.jpg"
mode="ascii"
/>
);
}RGB Rasterization
<ImageToAnything
src="https://example.com/photo.jpg"
mode="rgb-raster"
options={{
rgbRaster: {
layout: 'split', // 'split' | 'overlay' | 'separate'
channels: ['r', 'g', 'b'],
intensityMap: false,
gridLines: true,
dotMode: 'halftone', // 'none' | 'halftone' | 'inverse' | 'variable'
baseDotSize: 8,
dotSizeVariation: 0.8,
dotShape: 'circle', // 'circle' | 'square' | 'diamond'
dotSpacing: 2,
},
}}
/>CMYK Rasterization
<ImageToAnything
src="https://example.com/photo.jpg"
mode="cmyk-raster"
options={{
cmykRaster: {
layout: 'separate',
channels: ['c', 'm', 'y', 'k'],
dotMode: 'halftone',
baseDotSize: 6,
dotSizeVariation: 0.7,
dotShape: 'circle',
dotSpacing: 3,
gridLines: true,
angleOffset: true, // Authentic print simulation
},
}}
/>Pixelate Effect
<ImageToAnything
src="https://example.com/photo.jpg"
mode="pixelate"
options={{
pixelate: {
blockSize: 8,
quantizeColors: true,
colorLevels: 16,
},
}}
/>Edge Detection
<ImageToAnything
src="https://example.com/photo.jpg"
mode="edges"
options={{
edges: {
threshold: 50,
invert: false,
lineColor: '#000000',
backgroundColor: '#ffffff',
},
}}
/>Halftone Effect
<ImageToAnything
src="https://example.com/photo.jpg"
mode="halftone"
options={{
halftone: {
dotSize: 8,
angle: 45,
shape: 'circle', // 'circle' | 'square' | 'line'
backgroundColor: '#ffffff',
},
}}
/>With Filters and Animation
<ImageToAnything
src="https://example.com/photo.jpg"
mode="ascii"
options={{
filters: {
brightness: 1.2,
contrast: 1.1,
saturation: 1.5,
hue: 45,
},
movement: {
enabled: true,
speed: 3,
direction: "random",
},
}}
/>Posterize Effect
<ImageToAnything
src="https://example.com/photo.jpg"
mode="posterize"
options={{
posterize: {
levels: 8, // 2-255 color levels
edgeDetection: true, // Add edge detection
edgeThickness: 2, // Edge line thickness
},
}}
/>Stipple Effect
<ImageToAnything
src="https://example.com/photo.jpg"
mode="stipple"
options={{
stipple: {
dotDensity: 1.2, // Density of dots
minDotSize: 1, // Minimum dot size
maxDotSize: 6, // Maximum dot size
dotShape: 'circle', // 'circle' | 'square' | 'triangle'
colorMode: 'limited', // 'full' | 'monochrome' | 'limited'
backgroundColor: '#ffffff',
},
}}
/>Complete Example with All Options
<ImageToAnything
src="https://example.com/image.jpg"
mode="dithered"
options={{
quality: 100,
color: {
backgroundColor: "#ffffff",
palette: ["#97ef13", "#b81010", "green"],
},
ascii: {
allowedCharacters: " .:-=+*#%@",
blacklistedCharacters: "ABCDEFGH",
},
dithered: {
algorithm: "floyd-steinberg",
dotSize: 2,
dotBaseColor: "#000000",
dotShape: <polygon points="0,0 10,5 0,10" />,
},
format: "canvas",
filters: {
brightness: 1.2,
contrast: 1.1,
saturation: 1.5,
hue: 45,
blur: 0,
},
movement: {
enabled: true,
speed: 3,
direction: "random",
},
}}
onConvert={(result) => console.log('Converted!', result)}
onError={(error) => console.error('Error:', error)}
onProgress={(event) => console.log(`${event.stage}: ${event.progress}%`)}
onClick={(e) => console.log('Clicked')}
onMouseOver={(e) => console.log('Hover')}
/>Viewport System
The ASCII mode includes a powerful viewport system that allows you to control the character grid independently of the display size:
Viewport Options
interface ViewportOptions {
columns?: number; // Number of characters per row
rows?: number; // Number of character rows
autoCalculate?: boolean; // Auto-calculate from aspect ratio
}Viewport Control Examples
// Fixed 80x24 terminal size
<ImageToAnything
src="https://example.com/photo.jpg"
mode="ascii"
options={{
ascii: {
viewport: {
columns: 80,
rows: 24,
},
},
}}
/>
// Auto-calculate with 80-column default
<ImageToAnything
src="https://example.com/photo.jpg"
mode="ascii"
options={{
ascii: {
viewport: {
columns: 80,
autoCalculate: true,
},
},
}}
/>
// High-resolution ASCII art
<ImageToAnything
src="https://example.com/photo.jpg"
mode="ascii"
options={{
ascii: {
viewport: {
columns: 200,
rows: 0, // Auto-calculate height
},
},
}}
/>Export Functionality
ImageToAnything provides comprehensive export capabilities through the ref interface:
Export Methods
import { useRef } from 'react';
import { ImageToAnything, ImageToAnythingRef } from 'image-to-anything';
function ExportExample() {
const imageRef = useRef<ImageToAnythingRef>(null);
const handleExportJPG = async () => {
const blob = await imageRef.current?.exportAsJPG(0.9);
// Use blob for upload, preview, or download
};
const handleExportPNG = async () => {
const blob = await imageRef.current?.exportAsPNG();
// Use blob...
};
const handleExportSVG = async () => {
const svgString = await imageRef.current?.exportAsSVG();
// Use SVG string...
};
const handleDownload = async () => {
await imageRef.current?.download('png', 'my-image.png');
// Direct file download
};
const handleCustomDownload = async () => {
await imageRef.current?.download('jpg', 'artwork.jpg', 0.85);
// Custom format, filename, and quality
};
const getCurrentResult = () => {
const result = imageRef.current?.getResult();
console.log('Current conversion result:', result);
};
return (
<div>
<ImageToAnything
ref={imageRef}
src="https://example.com/photo.jpg"
mode="ascii"
/>
<button onClick={handleExportJPG}>Export as JPG</button>
<button onClick={handleExportPNG}>Export as PNG</button>
<button onClick={handleExportSVG}>Export as SVG</button>
<button onClick={handleDownload}>Download PNG</button>
<button onClick={getCurrentResult}>Get Result</button>
</div>
);
}Export Formats
- JPG: Best for photographs with configurable quality (0-1)
- PNG: Lossless format with transparency support
- SVG: Vector format for dithered modes with scalable quality
Dithering Algorithms
Floyd-Steinberg
Classic error diffusion algorithm that produces smooth gradients. Best for photographic images.
Atkinson
Developed for the original Macintosh. Creates lighter, more artistic results with preserved highlights.
Bayer (Ordered Dithering)
Uses a pre-computed matrix for consistent patterns. Fast and good for textures.
Performance Optimization
The library includes several performance optimizations:
- LRU Caching: Conversion results are cached to avoid redundant processing
- Optimized Canvas Operations: Uses
willReadFrequentlyhint and batched operations - Typed Arrays: Uses
Uint8ClampedArrayfor efficient pixel manipulation - Lookup Tables: Pre-computed character-to-brightness mappings for ASCII conversion
- Progressive Rendering: Large images are processed in chunks with progress callbacks
- Memory Management: Automatic cleanup and disposal of canvas contexts
Performance Tips
- Use appropriate image sizes: Downscale large images before conversion
- Enable caching: Reuse the same
srcandoptionswhen possible - Limit filter usage: Filters add processing overhead
- Choose the right algorithm: Bayer is fastest, Floyd-Steinberg is highest quality
Browser Support
- Chrome/Edge: ✅ Full support
- Firefox: ✅ Full support
- Safari: ✅ Full support
- Mobile browsers: ✅ Full support
Requires modern browser with Canvas API support.
TypeScript
Full TypeScript support with exported type definitions:
import type {
ImageToAnythingProps,
ImageToAnythingRef,
ConversionMode,
OutputFormat,
DitheringAlgorithm,
MovementDirection,
ColorOptions,
AsciiOptions,
ViewportOptions,
DitheredOptions,
FilterOptions,
MovementOptions,
ConversionOptions,
ConversionResult,
ProgressEvent,
RGBRasterOptions,
CMYKRasterOptions,
HalftoneOptions,
EdgesOptions,
PixelateOptions,
PosterizeOptions,
StippleOptions,
} from 'image-to-anything';ImageToAnythingRef
The ref provides access to export functionality:
interface ImageToAnythingRef {
exportAsJPG: (quality?: number) => Promise<Blob>;
exportAsPNG: () => Promise<Blob>;
exportAsSVG: () => Promise<string>;
download: (format: 'jpg' | 'png' | 'svg', filename?: string, quality?: number) => Promise<void>;
getResult: () => ConversionResult | null;
}Development
# Install dependencies
npm install
# Run demo app (interactive playground)
npm run demo
# Build library
npm run build
# Run tests
npm test
# Run tests with UI
npm run test:ui
# Preview build
npm run previewDemo App
The demo app showcases all features:
cd tests/demo
npm install
npm run devOpen http://localhost:3000 to explore:
- All 9 conversion modes
- Real-time parameter adjustment
- Image upload (URL or file)
- Export functionality
- Interactive examples
Build Output
npm run buildCreates:
dist/index.mjs- ES Moduledist/index.js- CommonJSdist/index.d.ts- TypeScript definitions
Project Structure
image-to-anything/
├── src/
│ ├── components/
│ │ └── ImageToAnything.tsx # Main React component
│ ├── converters/ # All conversion algorithms
│ │ ├── ascii.ts # ASCII art conversion
│ │ ├── dithering.ts # Dithering algorithms
│ │ ├── rgbRaster.ts # RGB channel separation
│ │ ├── cmykRaster.ts # CMYK print simulation
│ │ ├── halftone.ts # Halftone effects
│ │ ├── edges.ts # Edge detection
│ │ └── pixelate.ts # Pixelation effects
│ ├── utils/
│ │ ├── imageLoader.ts # Image loading & filters
│ │ ├── svgRenderer.ts # SVG to canvas conversion
│ │ ├── universalExporter.ts # Export functionality
│ │ └── performance.ts # Caching & optimization
│ ├── types/
│ │ └── index.ts # Complete TypeScript definitions
│ └── index.ts # Main exports
├── tests/
│ ├── unit/ # Vitest unit tests
│ └── demo/ # Interactive demo app
├── dist/ # Build output
└── README.md # This documentationChangelog
v0.0.10 (March 17, 2026)
🎨 New ASCII Art Features
✨ Dynamic Font Weight: Maps brightness to font-weight (100-900 range)
- Darker areas → bolder fonts, lighter areas → thinner fonts
- Creates depth and emphasis in ASCII art
- Supported in all output formats (HTML, SVG, Canvas, Base64)
🎲 Character Randomization: Controlled randomness for artistic variation
- 0-1 factor: 0 = exact behavior, 1 = maximum randomness
- Smart algorithm considers color weight while adding variation
- Prioritized visual quality over performance
🎛️ Enhanced Demo App: Added interactive controls for new features
- Dynamic font-weight toggle with descriptive labels
- Randomization slider (0-1 range) with real-time preview
- Comprehensive testing interface
📚 Updated Documentation: Complete API reference and examples
- Detailed feature explanations with use cases
- Multiple code examples showing combinations
- Performance and visual quality considerations
v0.0.9
🔧 Major Refactor & Performance Improvements
- Complete ASCII converter rewrite for better performance
- Enhanced viewport system for precise character grid control
- Improved type safety and error handling
- Updated demo app with all conversion modes
License
MIT © Luca Mack
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Acknowledgments
- Floyd-Steinberg dithering algorithm
- Atkinson dithering algorithm
- Bayer ordered dithering
- Canvas API for image processing
- React for component architecture
- TypeScript for type safety
ImageToAnything - Convert images to anything with zero dependencies. Perfect for creating unique visual effects, artistic renderings, and creative image processing in your React applications.
