asciify-engine 1.0.37 → 1.0.39
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/README.md +2 -0
- package/dist/index.cjs +34 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +25 -1
- package/dist/index.d.ts +25 -1
- package/dist/index.js +34 -3
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -387,6 +387,8 @@ Used by `asciify()`, `asciifyGif()`, and `asciifyVideo()`:
|
|
|
387
387
|
| `artStyle` | `ArtStyle` | `'classic'` | Art style preset (see `ART_STYLE_PRESETS`) |
|
|
388
388
|
| `ditherStrength` | `number` | `0` | Floyd-Steinberg dither intensity (0–1) |
|
|
389
389
|
| `dotSizeRatio` | `number` | `0.8` | Dot size when `renderMode === 'dots'` (fraction of cell) |
|
|
390
|
+
| `charAspect` | `number` | `0.55` | Width ÷ height of a single output character. Set to `0.5` for terminal emulators, `0.52` for browser `line-height: 1.15`, `0.55` for `line-height: 1.09`. Ensuring this matches your rendering environment keeps the output proportional to the source. |
|
|
391
|
+
| `normalize` | `boolean` | `false` | Auto-stretch the luminance range of the frame before charset mapping. Maximises detail and contrast for low-contrast or muted images. |
|
|
390
392
|
|
|
391
393
|
### Art Styles (`artStyle`)
|
|
392
394
|
|
package/dist/index.cjs
CHANGED
|
@@ -112,6 +112,8 @@ var DEFAULT_OPTIONS = {
|
|
|
112
112
|
animationSpeed: 1,
|
|
113
113
|
dotSizeRatio: 0.8,
|
|
114
114
|
ditherStrength: 0,
|
|
115
|
+
charAspect: 0.55,
|
|
116
|
+
normalize: false,
|
|
115
117
|
hoverStrength: 0,
|
|
116
118
|
hoverRadius: 0.2,
|
|
117
119
|
hoverEffect: "spotlight",
|
|
@@ -606,7 +608,7 @@ function imageToAsciiFrame(source, options, targetWidth, targetHeight) {
|
|
|
606
608
|
if (srcWidth === 0 || srcHeight === 0) {
|
|
607
609
|
return { frame: [], cols: 0, rows: 0 };
|
|
608
610
|
}
|
|
609
|
-
const charAspect =
|
|
611
|
+
const charAspect = options.charAspect;
|
|
610
612
|
const cellW = options.fontSize * options.charSpacing;
|
|
611
613
|
const cellH = options.fontSize / charAspect * options.charSpacing;
|
|
612
614
|
const renderW = targetWidth || srcWidth;
|
|
@@ -620,6 +622,18 @@ function imageToAsciiFrame(source, options, targetWidth, targetHeight) {
|
|
|
620
622
|
ctx.drawImage(source, 0, 0, cols, rows);
|
|
621
623
|
const imageData = ctx.getImageData(0, 0, cols, rows);
|
|
622
624
|
const pixels = imageData.data;
|
|
625
|
+
let normMin = 0;
|
|
626
|
+
let normRange = 255;
|
|
627
|
+
if (options.normalize) {
|
|
628
|
+
let lo = 255, hi = 0;
|
|
629
|
+
for (let k = 0; k < pixels.length; k += 4) {
|
|
630
|
+
const l = 0.299 * pixels[k] + 0.587 * pixels[k + 1] + 0.114 * pixels[k + 2];
|
|
631
|
+
if (l < lo) lo = l;
|
|
632
|
+
if (l > hi) hi = l;
|
|
633
|
+
}
|
|
634
|
+
normMin = lo;
|
|
635
|
+
normRange = hi > lo ? hi - lo : 255;
|
|
636
|
+
}
|
|
623
637
|
const frame = [];
|
|
624
638
|
for (let y = 0; y < rows; y++) {
|
|
625
639
|
const row = [];
|
|
@@ -629,7 +643,8 @@ function imageToAsciiFrame(source, options, targetWidth, targetHeight) {
|
|
|
629
643
|
const g = pixels[i + 1];
|
|
630
644
|
const b = pixels[i + 2];
|
|
631
645
|
const a = pixels[i + 3];
|
|
632
|
-
const
|
|
646
|
+
const rawLum = 0.299 * r + 0.587 * g + 0.114 * b;
|
|
647
|
+
const lum = options.normalize ? (rawLum - normMin) / normRange * 255 : rawLum;
|
|
633
648
|
const adjustedLum = adjustLuminance(lum, options.brightness, options.contrast);
|
|
634
649
|
const ditheredLum = applyDither(adjustedLum, x, y, options.ditherStrength);
|
|
635
650
|
const char = options.customText ? customTextToChar(ditheredLum, options.customText, x, y, cols, options.invert) : luminanceToChar(ditheredLum, options.charset, options.invert);
|
|
@@ -2014,6 +2029,22 @@ function _parseColor(c) {
|
|
|
2014
2029
|
if (rgb) return { r: +rgb[1], g: +rgb[2], b: +rgb[3] };
|
|
2015
2030
|
return null;
|
|
2016
2031
|
}
|
|
2032
|
+
var BACKGROUND_TYPES = [
|
|
2033
|
+
"wave",
|
|
2034
|
+
"rain",
|
|
2035
|
+
"stars",
|
|
2036
|
+
"pulse",
|
|
2037
|
+
"noise",
|
|
2038
|
+
"grid",
|
|
2039
|
+
"aurora",
|
|
2040
|
+
"silk",
|
|
2041
|
+
"void",
|
|
2042
|
+
"morph",
|
|
2043
|
+
"fire",
|
|
2044
|
+
"dna",
|
|
2045
|
+
"terrain",
|
|
2046
|
+
"circuit"
|
|
2047
|
+
];
|
|
2017
2048
|
function asciiBackground(target, options = {}) {
|
|
2018
2049
|
const {
|
|
2019
2050
|
type = "wave",
|
|
@@ -2427,6 +2458,7 @@ async function asciifyWebcam(canvas, {
|
|
|
2427
2458
|
}
|
|
2428
2459
|
|
|
2429
2460
|
exports.ART_STYLE_PRESETS = ART_STYLE_PRESETS;
|
|
2461
|
+
exports.BACKGROUND_TYPES = BACKGROUND_TYPES;
|
|
2430
2462
|
exports.CHARSETS = CHARSETS;
|
|
2431
2463
|
exports.DEFAULT_OPTIONS = DEFAULT_OPTIONS;
|
|
2432
2464
|
exports.HOVER_PRESETS = HOVER_PRESETS;
|