ts-ascii-engine 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +570 -0
- package/dist/core/ascii-engine.d.ts +108 -0
- package/dist/core/ascii-engine.d.ts.map +1 -0
- package/dist/core/ascii-engine.js +324 -0
- package/dist/core/ascii-engine.js.map +1 -0
- package/dist/index.d.ts +152 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +166 -0
- package/dist/index.js.map +1 -0
- package/dist/types/interfaces.d.ts +174 -0
- package/dist/types/interfaces.d.ts.map +1 -0
- package/dist/types/interfaces.js +33 -0
- package/dist/types/interfaces.js.map +1 -0
- package/dist/utils/canvas-helpers.d.ts +96 -0
- package/dist/utils/canvas-helpers.d.ts.map +1 -0
- package/dist/utils/canvas-helpers.js +274 -0
- package/dist/utils/canvas-helpers.js.map +1 -0
- package/dist-esm/core/ascii-engine.js +320 -0
- package/dist-esm/core/ascii-engine.js.map +1 -0
- package/dist-esm/index.js +153 -0
- package/dist-esm/index.js.map +1 -0
- package/dist-esm/types/interfaces.js +30 -0
- package/dist-esm/types/interfaces.js.map +1 -0
- package/dist-esm/utils/canvas-helpers.js +265 -0
- package/dist-esm/utils/canvas-helpers.js.map +1 -0
- package/package.json +43 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 ts-ascii-engine
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,570 @@
|
|
|
1
|
+
# ts-ascii-engine
|
|
2
|
+
|
|
3
|
+
A high-performance, zero-dependency TypeScript library for converting images, video streams, and text into ASCII art. Framework agnostic and optimized for both browser and Node.js environments.
|
|
4
|
+
|
|
5
|
+
## Documentation
|
|
6
|
+
|
|
7
|
+
- **[Interactive API Documentation](docs/index.html)** - Complete API reference with live demos
|
|
8
|
+
- **[Live Examples](examples/)** - Working examples you can try right now
|
|
9
|
+
- **[Full API Reference](API_DOCUMENTATION.md)** - Detailed markdown documentation
|
|
10
|
+
- **[Quick Start Guide](QUICK_START.md)** - Get started in 5 minutes
|
|
11
|
+
- **[Testing Guide](TESTING_GUIDE.md)** - How to run and test examples
|
|
12
|
+
|
|
13
|
+
## Features
|
|
14
|
+
|
|
15
|
+
- **Zero Dependencies** - Pure TypeScript implementation
|
|
16
|
+
- **Framework Agnostic** - Works with vanilla JS, React, Vue, Angular, and any other framework
|
|
17
|
+
- **High Performance** - Optimized with typed arrays and minimal garbage collection
|
|
18
|
+
- **Tree-Shakable** - Import only what you need
|
|
19
|
+
- **Fully Typed** - Complete TypeScript definitions
|
|
20
|
+
- **Versatile Input** - Supports images, video streams, canvas, and text
|
|
21
|
+
- **Customizable** - Multiple charsets, aspect ratio correction, color support
|
|
22
|
+
- **Web Worker Ready** - Easy integration with Web Workers for off-thread processing
|
|
23
|
+
|
|
24
|
+
## Installation
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
npm install ts-ascii-engine
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Quick Start
|
|
31
|
+
|
|
32
|
+
```typescript
|
|
33
|
+
import { AsciiGenerator, CharsetPreset } from "ts-ascii-engine";
|
|
34
|
+
|
|
35
|
+
// Create generator instance
|
|
36
|
+
const generator = new AsciiGenerator({
|
|
37
|
+
charset: CharsetPreset.BLOCK,
|
|
38
|
+
width: 80,
|
|
39
|
+
colored: false,
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
// Convert an image
|
|
43
|
+
const img = document.querySelector("img");
|
|
44
|
+
const result = generator.convertImage(img);
|
|
45
|
+
|
|
46
|
+
// Display as text
|
|
47
|
+
console.log(result.text);
|
|
48
|
+
|
|
49
|
+
// Or display as HTML
|
|
50
|
+
document.body.innerHTML = result.html;
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## API Reference
|
|
54
|
+
|
|
55
|
+
### AsciiGenerator
|
|
56
|
+
|
|
57
|
+
The main class for converting images and text to ASCII art.
|
|
58
|
+
|
|
59
|
+
#### Constructor
|
|
60
|
+
|
|
61
|
+
```typescript
|
|
62
|
+
const generator = new AsciiGenerator(config?: AsciiConfig);
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
**Configuration Options:**
|
|
66
|
+
|
|
67
|
+
| Option | Type | Default | Description |
|
|
68
|
+
| ------------- | ------------------------- | ------------------------ | -------------------------------- |
|
|
69
|
+
| `charset` | `CharsetPreset \| string` | `CharsetPreset.STANDARD` | Character set for rendering |
|
|
70
|
+
| `inverted` | `boolean` | `false` | Invert brightness mapping |
|
|
71
|
+
| `colored` | `boolean` | `false` | Include color information |
|
|
72
|
+
| `aspectRatio` | `number` | `0.55` | Font aspect ratio correction |
|
|
73
|
+
| `width` | `number` | `0` (auto) | Target width in characters |
|
|
74
|
+
| `height` | `number` | `0` (auto) | Target height in characters |
|
|
75
|
+
| `optimized` | `boolean` | `true` | Enable performance optimizations |
|
|
76
|
+
|
|
77
|
+
#### Methods
|
|
78
|
+
|
|
79
|
+
##### `convertImage(source: ImageSource): AsciiOutput`
|
|
80
|
+
|
|
81
|
+
Converts an image source to ASCII art.
|
|
82
|
+
|
|
83
|
+
**Parameters:**
|
|
84
|
+
|
|
85
|
+
- `source` - `HTMLImageElement`, `HTMLVideoElement`, `HTMLCanvasElement`, or `ImageData`
|
|
86
|
+
|
|
87
|
+
**Returns:** `AsciiOutput` object containing:
|
|
88
|
+
|
|
89
|
+
- `text: string` - Raw ASCII text with newlines
|
|
90
|
+
- `html: string` - HTML formatted output
|
|
91
|
+
- `characters: string[][]` - 2D array of characters
|
|
92
|
+
- `colors?: CharColor[][]` - 2D array of colors (if `colored: true`)
|
|
93
|
+
- `metadata: AsciiMetadata` - Processing information
|
|
94
|
+
|
|
95
|
+
##### `convertText(text: string, options?: TextToAsciiOptions): AsciiOutput`
|
|
96
|
+
|
|
97
|
+
Converts text to ASCII art by rendering it with a specified font first.
|
|
98
|
+
|
|
99
|
+
**Parameters:**
|
|
100
|
+
|
|
101
|
+
- `text` - String to convert
|
|
102
|
+
- `options` - Font and rendering options
|
|
103
|
+
|
|
104
|
+
**Options:**
|
|
105
|
+
|
|
106
|
+
| Option | Type | Default | Description |
|
|
107
|
+
| ----------------- | ------------------ | ----------- | ------------------- |
|
|
108
|
+
| `font` | `string` | `'Arial'` | Font family |
|
|
109
|
+
| `fontSize` | `number` | `48` | Font size in pixels |
|
|
110
|
+
| `fontWeight` | `string \| number` | `'normal'` | Font weight |
|
|
111
|
+
| `fontStyle` | `string` | `'normal'` | Font style |
|
|
112
|
+
| `color` | `string` | `'#000000'` | Text color |
|
|
113
|
+
| `backgroundColor` | `string` | `'#ffffff'` | Background color |
|
|
114
|
+
| `padding` | `number` | `10` | Padding in pixels |
|
|
115
|
+
|
|
116
|
+
##### `generateColorMap(source: ImageSource): CharColor[][]`
|
|
117
|
+
|
|
118
|
+
Generates a 2D array of color data separately from ASCII characters.
|
|
119
|
+
|
|
120
|
+
##### `updateConfig(config: Partial<AsciiConfig>): void`
|
|
121
|
+
|
|
122
|
+
Updates configuration dynamically.
|
|
123
|
+
|
|
124
|
+
##### `getConfig(): Readonly<Required<AsciiConfig>>`
|
|
125
|
+
|
|
126
|
+
Returns the current configuration.
|
|
127
|
+
|
|
128
|
+
### Charset Presets
|
|
129
|
+
|
|
130
|
+
Built-in character sets optimized for different use cases:
|
|
131
|
+
|
|
132
|
+
```typescript
|
|
133
|
+
enum CharsetPreset {
|
|
134
|
+
BLOCK = "BLOCK", // ██▓▒░
|
|
135
|
+
STANDARD = "STANDARD", // @%#*+=-:.
|
|
136
|
+
MINIMAL = "MINIMAL", // @+.
|
|
137
|
+
EXTENDED = "EXTENDED", // Full 70+ character set
|
|
138
|
+
CUSTOM = "CUSTOM", // Use custom string
|
|
139
|
+
}
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
**Custom Charset Example:**
|
|
143
|
+
|
|
144
|
+
```typescript
|
|
145
|
+
const generator = new AsciiGenerator({
|
|
146
|
+
charset: "█▓▒░ ", // Custom characters, dark to light
|
|
147
|
+
});
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
## Usage Examples
|
|
151
|
+
|
|
152
|
+
### Basic Image Conversion
|
|
153
|
+
|
|
154
|
+
```typescript
|
|
155
|
+
import { AsciiGenerator, CharsetPreset } from "ts-ascii-engine";
|
|
156
|
+
|
|
157
|
+
const generator = new AsciiGenerator({
|
|
158
|
+
charset: CharsetPreset.STANDARD,
|
|
159
|
+
width: 100,
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
const img = new Image();
|
|
163
|
+
img.onload = () => {
|
|
164
|
+
const result = generator.convertImage(img);
|
|
165
|
+
document.getElementById("output").innerHTML = result.html;
|
|
166
|
+
};
|
|
167
|
+
img.src = "path/to/image.jpg";
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### Video Stream (Real-time)
|
|
171
|
+
|
|
172
|
+
```typescript
|
|
173
|
+
const video = document.querySelector("video");
|
|
174
|
+
const generator = new AsciiGenerator({
|
|
175
|
+
charset: CharsetPreset.BLOCK,
|
|
176
|
+
colored: true,
|
|
177
|
+
width: 80,
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
function renderFrame() {
|
|
181
|
+
const ascii = generator.convertImage(video);
|
|
182
|
+
document.getElementById("output").innerHTML = ascii.html;
|
|
183
|
+
requestAnimationFrame(renderFrame);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
video.addEventListener("play", renderFrame);
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
### Text to ASCII Banner
|
|
190
|
+
|
|
191
|
+
```typescript
|
|
192
|
+
const generator = new AsciiGenerator({
|
|
193
|
+
charset: CharsetPreset.STANDARD,
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
const result = generator.convertText("HELLO WORLD", {
|
|
197
|
+
font: "Arial",
|
|
198
|
+
fontSize: 72,
|
|
199
|
+
fontWeight: "bold",
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
console.log(result.text);
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
### Webcam Stream
|
|
206
|
+
|
|
207
|
+
```typescript
|
|
208
|
+
const video = document.createElement("video");
|
|
209
|
+
const generator = new AsciiGenerator({ width: 80, colored: true });
|
|
210
|
+
|
|
211
|
+
navigator.mediaDevices.getUserMedia({ video: true }).then((stream) => {
|
|
212
|
+
video.srcObject = stream;
|
|
213
|
+
video.play();
|
|
214
|
+
|
|
215
|
+
function render() {
|
|
216
|
+
const ascii = generator.convertImage(video);
|
|
217
|
+
document.body.innerHTML = ascii.html;
|
|
218
|
+
requestAnimationFrame(render);
|
|
219
|
+
}
|
|
220
|
+
render();
|
|
221
|
+
});
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
### Dynamic Configuration
|
|
225
|
+
|
|
226
|
+
```typescript
|
|
227
|
+
const generator = new AsciiGenerator();
|
|
228
|
+
|
|
229
|
+
// Update settings on the fly
|
|
230
|
+
generator.updateConfig({ width: 120, colored: true });
|
|
231
|
+
|
|
232
|
+
// Toggle inversion
|
|
233
|
+
generator.updateConfig({ inverted: true });
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
## Framework Integration
|
|
237
|
+
|
|
238
|
+
### React
|
|
239
|
+
|
|
240
|
+
```tsx
|
|
241
|
+
import { AsciiGenerator, CharsetPreset } from "ts-ascii-engine";
|
|
242
|
+
import { useEffect, useRef, useState } from "react";
|
|
243
|
+
|
|
244
|
+
function AsciiImage({ src }: { src: string }) {
|
|
245
|
+
const [html, setHtml] = useState("");
|
|
246
|
+
const generatorRef = useRef(
|
|
247
|
+
new AsciiGenerator({
|
|
248
|
+
charset: CharsetPreset.BLOCK,
|
|
249
|
+
width: 100,
|
|
250
|
+
}),
|
|
251
|
+
);
|
|
252
|
+
|
|
253
|
+
useEffect(() => {
|
|
254
|
+
const img = new Image();
|
|
255
|
+
img.onload = () => {
|
|
256
|
+
const result = generatorRef.current.convertImage(img);
|
|
257
|
+
setHtml(result.html);
|
|
258
|
+
};
|
|
259
|
+
img.src = src;
|
|
260
|
+
}, [src]);
|
|
261
|
+
|
|
262
|
+
return <div dangerouslySetInnerHTML={{ __html: html }} />;
|
|
263
|
+
}
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
### Vue 3 (Composition API)
|
|
267
|
+
|
|
268
|
+
```vue
|
|
269
|
+
<template>
|
|
270
|
+
<div v-html="asciiHtml"></div>
|
|
271
|
+
</template>
|
|
272
|
+
|
|
273
|
+
<script setup lang="ts">
|
|
274
|
+
import { ref, onMounted, watch } from "vue";
|
|
275
|
+
import { AsciiGenerator, CharsetPreset } from "ts-ascii-engine";
|
|
276
|
+
|
|
277
|
+
const props = defineProps<{ src: string }>();
|
|
278
|
+
const asciiHtml = ref("");
|
|
279
|
+
|
|
280
|
+
const generator = new AsciiGenerator({
|
|
281
|
+
charset: CharsetPreset.STANDARD,
|
|
282
|
+
width: 80,
|
|
283
|
+
});
|
|
284
|
+
|
|
285
|
+
const convert = (src: string) => {
|
|
286
|
+
const img = new Image();
|
|
287
|
+
img.onload = () => {
|
|
288
|
+
const result = generator.convertImage(img);
|
|
289
|
+
asciiHtml.value = result.html;
|
|
290
|
+
};
|
|
291
|
+
img.src = src;
|
|
292
|
+
};
|
|
293
|
+
|
|
294
|
+
onMounted(() => convert(props.src));
|
|
295
|
+
watch(() => props.src, convert);
|
|
296
|
+
</script>
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
### Angular
|
|
300
|
+
|
|
301
|
+
```typescript
|
|
302
|
+
// ascii.service.ts
|
|
303
|
+
import { Injectable } from "@angular/core";
|
|
304
|
+
import {
|
|
305
|
+
AsciiGenerator,
|
|
306
|
+
CharsetPreset,
|
|
307
|
+
AsciiConfig,
|
|
308
|
+
AsciiOutput,
|
|
309
|
+
} from "ts-ascii-engine";
|
|
310
|
+
|
|
311
|
+
@Injectable({
|
|
312
|
+
providedIn: "root",
|
|
313
|
+
})
|
|
314
|
+
export class AsciiService {
|
|
315
|
+
private generator: AsciiGenerator;
|
|
316
|
+
|
|
317
|
+
constructor() {
|
|
318
|
+
this.generator = new AsciiGenerator({
|
|
319
|
+
charset: CharsetPreset.STANDARD,
|
|
320
|
+
width: 80,
|
|
321
|
+
});
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
convertImage(source: HTMLImageElement | HTMLVideoElement): AsciiOutput {
|
|
325
|
+
return this.generator.convertImage(source);
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
convertText(text: string, options = {}): AsciiOutput {
|
|
329
|
+
return this.generator.convertText(text, options);
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
updateConfig(config: Partial<AsciiConfig>): void {
|
|
333
|
+
this.generator.updateConfig(config);
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
```typescript
|
|
339
|
+
// ascii.component.ts
|
|
340
|
+
import { Component, Input, OnInit } from "@angular/core";
|
|
341
|
+
import { AsciiService } from "./ascii.service";
|
|
342
|
+
import { DomSanitizer, SafeHtml } from "@angular/platform-browser";
|
|
343
|
+
|
|
344
|
+
@Component({
|
|
345
|
+
selector: "app-ascii-image",
|
|
346
|
+
template: '<div [innerHTML]="asciiHtml"></div>',
|
|
347
|
+
})
|
|
348
|
+
export class AsciiImageComponent implements OnInit {
|
|
349
|
+
@Input() src!: string;
|
|
350
|
+
asciiHtml: SafeHtml = "";
|
|
351
|
+
|
|
352
|
+
constructor(
|
|
353
|
+
private asciiService: AsciiService,
|
|
354
|
+
private sanitizer: DomSanitizer,
|
|
355
|
+
) {}
|
|
356
|
+
|
|
357
|
+
ngOnInit() {
|
|
358
|
+
const img = new Image();
|
|
359
|
+
img.onload = () => {
|
|
360
|
+
const result = this.asciiService.convertImage(img);
|
|
361
|
+
this.asciiHtml = this.sanitizer.bypassSecurityTrustHtml(result.html);
|
|
362
|
+
};
|
|
363
|
+
img.src = this.src;
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
## Web Worker Integration
|
|
369
|
+
|
|
370
|
+
Offload ASCII processing to a background thread for better performance:
|
|
371
|
+
|
|
372
|
+
### Worker Script (worker.ts)
|
|
373
|
+
|
|
374
|
+
```typescript
|
|
375
|
+
import { AsciiGenerator, CharsetPreset } from "ts-ascii-engine";
|
|
376
|
+
|
|
377
|
+
const generator = new AsciiGenerator({
|
|
378
|
+
charset: CharsetPreset.BLOCK,
|
|
379
|
+
colored: true,
|
|
380
|
+
});
|
|
381
|
+
|
|
382
|
+
self.onmessage = (e: MessageEvent) => {
|
|
383
|
+
const { imageData, config } = e.data;
|
|
384
|
+
|
|
385
|
+
if (config) {
|
|
386
|
+
generator.updateConfig(config);
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
const result = generator.convertImage(imageData);
|
|
390
|
+
self.postMessage(result);
|
|
391
|
+
};
|
|
392
|
+
```
|
|
393
|
+
|
|
394
|
+
### Main Thread
|
|
395
|
+
|
|
396
|
+
```typescript
|
|
397
|
+
const worker = new Worker("worker.js");
|
|
398
|
+
const video = document.querySelector("video");
|
|
399
|
+
|
|
400
|
+
function sendFrame() {
|
|
401
|
+
const canvas = document.createElement("canvas");
|
|
402
|
+
const ctx = canvas.getContext("2d");
|
|
403
|
+
canvas.width = video.videoWidth;
|
|
404
|
+
canvas.height = video.videoHeight;
|
|
405
|
+
ctx.drawImage(video, 0, 0);
|
|
406
|
+
|
|
407
|
+
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
|
|
408
|
+
worker.postMessage({ imageData });
|
|
409
|
+
|
|
410
|
+
requestAnimationFrame(sendFrame);
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
worker.onmessage = (e) => {
|
|
414
|
+
document.getElementById("output").innerHTML = e.data.html;
|
|
415
|
+
};
|
|
416
|
+
|
|
417
|
+
sendFrame();
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
## Advanced Usage
|
|
421
|
+
|
|
422
|
+
### Custom Color Rendering
|
|
423
|
+
|
|
424
|
+
```typescript
|
|
425
|
+
const generator = new AsciiGenerator({ colored: false });
|
|
426
|
+
const result = generator.convertImage(img);
|
|
427
|
+
const colors = generator.generateColorMap(img);
|
|
428
|
+
|
|
429
|
+
// Custom rendering logic
|
|
430
|
+
let html = "<pre>";
|
|
431
|
+
for (let y = 0; y < result.characters.length; y++) {
|
|
432
|
+
for (let x = 0; x < result.characters[y].length; x++) {
|
|
433
|
+
const char = result.characters[y][x];
|
|
434
|
+
const color = colors[y][x];
|
|
435
|
+
html += `<span style="color:rgb(${color.r},${color.g},${color.b})">${char}</span>`;
|
|
436
|
+
}
|
|
437
|
+
html += "\n";
|
|
438
|
+
}
|
|
439
|
+
html += "</pre>";
|
|
440
|
+
```
|
|
441
|
+
|
|
442
|
+
### Aspect Ratio Tuning
|
|
443
|
+
|
|
444
|
+
Different fonts have different aspect ratios. Adjust for your specific font:
|
|
445
|
+
|
|
446
|
+
```typescript
|
|
447
|
+
// For most monospace fonts (Courier, Consolas)
|
|
448
|
+
const generator = new AsciiGenerator({ aspectRatio: 0.55 });
|
|
449
|
+
|
|
450
|
+
// For wider fonts
|
|
451
|
+
const generator = new AsciiGenerator({ aspectRatio: 0.6 });
|
|
452
|
+
|
|
453
|
+
// For narrower fonts
|
|
454
|
+
const generator = new AsciiGenerator({ aspectRatio: 0.5 });
|
|
455
|
+
```
|
|
456
|
+
|
|
457
|
+
### Performance Monitoring
|
|
458
|
+
|
|
459
|
+
```typescript
|
|
460
|
+
const result = generator.convertImage(img);
|
|
461
|
+
console.log(`Processed in ${result.metadata.processingTime.toFixed(2)}ms`);
|
|
462
|
+
console.log(`Generated ${result.metadata.characterCount} characters`);
|
|
463
|
+
console.log(`Dimensions: ${result.metadata.width}x${result.metadata.height}`);
|
|
464
|
+
```
|
|
465
|
+
|
|
466
|
+
## Utility Functions
|
|
467
|
+
|
|
468
|
+
The library also exports utility functions for advanced use cases:
|
|
469
|
+
|
|
470
|
+
```typescript
|
|
471
|
+
import {
|
|
472
|
+
extractPixelData,
|
|
473
|
+
calculateLuminance,
|
|
474
|
+
luminanceToChar,
|
|
475
|
+
calculateDimensions,
|
|
476
|
+
renderTextToCanvas,
|
|
477
|
+
samplePixelColor,
|
|
478
|
+
rgbToCSS,
|
|
479
|
+
} from "ts-ascii-engine";
|
|
480
|
+
```
|
|
481
|
+
|
|
482
|
+
See TypeScript definitions for detailed documentation.
|
|
483
|
+
|
|
484
|
+
## Performance Tips
|
|
485
|
+
|
|
486
|
+
1. **Pre-size images** - Resize images before conversion for better performance
|
|
487
|
+
2. **Use Web Workers** - Offload processing for real-time video streams
|
|
488
|
+
3. **Optimize charset** - Shorter charsets process faster
|
|
489
|
+
4. **Disable colors** - Color processing adds overhead
|
|
490
|
+
5. **Limit dimensions** - Smaller output (width/height) = faster processing
|
|
491
|
+
6. **Reuse instances** - Create one generator and update config as needed
|
|
492
|
+
|
|
493
|
+
## Browser Compatibility
|
|
494
|
+
|
|
495
|
+
- Modern browsers with Canvas API support
|
|
496
|
+
- ES2020+ JavaScript environment
|
|
497
|
+
- Node.js 14+ (with canvas polyfill like `node-canvas`)
|
|
498
|
+
|
|
499
|
+
## Node.js Usage
|
|
500
|
+
|
|
501
|
+
For Node.js environments, you'll need a canvas implementation:
|
|
502
|
+
|
|
503
|
+
```bash
|
|
504
|
+
npm install canvas
|
|
505
|
+
```
|
|
506
|
+
|
|
507
|
+
```typescript
|
|
508
|
+
import { AsciiGenerator } from "ts-ascii-engine";
|
|
509
|
+
import { createCanvas, loadImage } from "canvas";
|
|
510
|
+
|
|
511
|
+
const generator = new AsciiGenerator();
|
|
512
|
+
|
|
513
|
+
loadImage("path/to/image.jpg").then((img) => {
|
|
514
|
+
const result = generator.convertImage(img as any);
|
|
515
|
+
console.log(result.text);
|
|
516
|
+
});
|
|
517
|
+
```
|
|
518
|
+
|
|
519
|
+
## TypeScript Support
|
|
520
|
+
|
|
521
|
+
Full TypeScript definitions are included. Import types as needed:
|
|
522
|
+
|
|
523
|
+
```typescript
|
|
524
|
+
import type {
|
|
525
|
+
AsciiConfig,
|
|
526
|
+
AsciiOutput,
|
|
527
|
+
AsciiMetadata,
|
|
528
|
+
CharColor,
|
|
529
|
+
TextToAsciiOptions,
|
|
530
|
+
ImageSource,
|
|
531
|
+
} from "ts-ascii-engine";
|
|
532
|
+
```
|
|
533
|
+
|
|
534
|
+
## License
|
|
535
|
+
|
|
536
|
+
MIT
|
|
537
|
+
|
|
538
|
+
## Development & Testing
|
|
539
|
+
|
|
540
|
+
### Setup
|
|
541
|
+
|
|
542
|
+
```bash
|
|
543
|
+
# Install dependencies
|
|
544
|
+
npm install
|
|
545
|
+
|
|
546
|
+
# Build the project
|
|
547
|
+
npm run build
|
|
548
|
+
```
|
|
549
|
+
|
|
550
|
+
### Running Tests
|
|
551
|
+
|
|
552
|
+
This project includes automated test suites for build verification and security constraints.
|
|
553
|
+
|
|
554
|
+
```bash
|
|
555
|
+
# Run build verification tests
|
|
556
|
+
npm test
|
|
557
|
+
|
|
558
|
+
# Run security limit tests
|
|
559
|
+
npm run test:security
|
|
560
|
+
```
|
|
561
|
+
|
|
562
|
+
For manual testing of visual examples, see the [Testing Guide](TESTING_GUIDE.md).
|
|
563
|
+
|
|
564
|
+
## Contributing
|
|
565
|
+
|
|
566
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
567
|
+
|
|
568
|
+
## Credits
|
|
569
|
+
|
|
570
|
+
Built with performance and developer experience in mind.
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core ASCII Generator Engine
|
|
3
|
+
* High-performance, zero-dependency ASCII art conversion
|
|
4
|
+
* @module core/ascii-engine
|
|
5
|
+
*/
|
|
6
|
+
import type { AsciiConfig, AsciiOutput, CharColor, ImageSource, TextToAsciiOptions } from '../types/interfaces';
|
|
7
|
+
/**
|
|
8
|
+
* High-performance ASCII art generator
|
|
9
|
+
* Converts images, video frames, and text into ASCII representation
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```typescript
|
|
13
|
+
* const generator = new AsciiGenerator({
|
|
14
|
+
* charset: CharsetPreset.BLOCK,
|
|
15
|
+
* colored: true,
|
|
16
|
+
* aspectRatio: 0.55
|
|
17
|
+
* });
|
|
18
|
+
*
|
|
19
|
+
* const result = generator.convertImage(imageElement);
|
|
20
|
+
* document.body.innerHTML = result.html;
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export declare class AsciiGenerator {
|
|
24
|
+
private readonly config;
|
|
25
|
+
private readonly charset;
|
|
26
|
+
/**
|
|
27
|
+
* Creates a new ASCII generator instance
|
|
28
|
+
*
|
|
29
|
+
* @param config - Configuration options for ASCII conversion
|
|
30
|
+
*/
|
|
31
|
+
constructor(config?: AsciiConfig);
|
|
32
|
+
/**
|
|
33
|
+
* Converts an image source to ASCII art
|
|
34
|
+
*
|
|
35
|
+
* @param source - Image, video, canvas, or ImageData to convert
|
|
36
|
+
* @returns Complete ASCII output with text, HTML, and metadata
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* ```typescript
|
|
40
|
+
* const img = document.querySelector('img');
|
|
41
|
+
* const ascii = generator.convertImage(img);
|
|
42
|
+
* console.log(ascii.text);
|
|
43
|
+
* ```
|
|
44
|
+
*/
|
|
45
|
+
convertImage(source: ImageSource): AsciiOutput;
|
|
46
|
+
/**
|
|
47
|
+
* Converts text into ASCII art by rendering it to canvas first
|
|
48
|
+
* Allows creating ASCII banners from any system font
|
|
49
|
+
*
|
|
50
|
+
* @param text - Text to convert
|
|
51
|
+
* @param options - Font and rendering options
|
|
52
|
+
* @returns ASCII output of the rendered text
|
|
53
|
+
*
|
|
54
|
+
* @example
|
|
55
|
+
* ```typescript
|
|
56
|
+
* const ascii = generator.convertText('HELLO', {
|
|
57
|
+
* font: 'Arial',
|
|
58
|
+
* fontSize: 72,
|
|
59
|
+
* fontWeight: 'bold'
|
|
60
|
+
* });
|
|
61
|
+
* console.log(ascii.text);
|
|
62
|
+
* ```
|
|
63
|
+
*/
|
|
64
|
+
convertText(text: string, options?: TextToAsciiOptions): AsciiOutput;
|
|
65
|
+
/**
|
|
66
|
+
* Generates a color map separately from character data
|
|
67
|
+
* Useful for advanced rendering scenarios
|
|
68
|
+
*
|
|
69
|
+
* @param source - Image source to extract colors from
|
|
70
|
+
* @returns 2D array of color data
|
|
71
|
+
*/
|
|
72
|
+
generateColorMap(source: ImageSource): CharColor[][];
|
|
73
|
+
/**
|
|
74
|
+
* Updates the configuration dynamically
|
|
75
|
+
* Useful for real-time parameter adjustments
|
|
76
|
+
*
|
|
77
|
+
* @param config - Partial configuration to update
|
|
78
|
+
*/
|
|
79
|
+
updateConfig(config: Partial<AsciiConfig>): void;
|
|
80
|
+
/**
|
|
81
|
+
* Gets the current configuration
|
|
82
|
+
*
|
|
83
|
+
* @returns Current configuration object (deep copy)
|
|
84
|
+
*/
|
|
85
|
+
getConfig(): Readonly<Required<AsciiConfig>>;
|
|
86
|
+
/**
|
|
87
|
+
* Processes pixel data into ASCII representation
|
|
88
|
+
* Core conversion algorithm with optional color support
|
|
89
|
+
*/
|
|
90
|
+
private processPixelData;
|
|
91
|
+
/**
|
|
92
|
+
* Resolves charset from preset or custom string
|
|
93
|
+
*/
|
|
94
|
+
private resolveCharset;
|
|
95
|
+
/**
|
|
96
|
+
* Validates configuration parameters
|
|
97
|
+
*/
|
|
98
|
+
private validateConfig;
|
|
99
|
+
/**
|
|
100
|
+
* Builds final HTML output with proper formatting
|
|
101
|
+
*/
|
|
102
|
+
private buildHtmlOutput;
|
|
103
|
+
/**
|
|
104
|
+
* Escapes HTML special characters to prevent XSS
|
|
105
|
+
*/
|
|
106
|
+
private escapeHtml;
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=ascii-engine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ascii-engine.d.ts","sourceRoot":"","sources":["../../src/core/ascii-engine.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EACV,WAAW,EACX,WAAW,EACX,SAAS,EACT,WAAW,EACX,kBAAkB,EAEnB,MAAM,qBAAqB,CAAC;AAY7B;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAwB;IAC/C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IAEjC;;;;OAIG;gBACS,MAAM,GAAE,WAAgB;IAmBpC;;;;;;;;;;;;OAYG;IACI,YAAY,CAAC,MAAM,EAAE,WAAW,GAAG,WAAW;IAuDrD;;;;;;;;;;;;;;;;;OAiBG;IACI,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,kBAAuB,GAAG,WAAW;IA2B/E;;;;;;OAMG;IACI,gBAAgB,CAAC,MAAM,EAAE,WAAW,GAAG,SAAS,EAAE,EAAE;IAqC3D;;;;;OAKG;IACI,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,WAAW,CAAC,GAAG,IAAI;IAgBvD;;;;OAIG;IACI,SAAS,IAAI,QAAQ,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;IAInD;;;OAGG;IACH,OAAO,CAAC,gBAAgB;IA0ExB;;OAEG;IACH,OAAO,CAAC,cAAc;IAsBtB;;OAEG;IACH,OAAO,CAAC,cAAc;IA6CtB;;OAEG;IACH,OAAO,CAAC,eAAe;IAQvB;;OAEG;IACH,OAAO,CAAC,UAAU;CAWnB"}
|