asciify-engine 1.0.38 → 1.0.40

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/dist/index.d.cts CHANGED
@@ -79,6 +79,24 @@ interface AsciiOptions {
79
79
  * `0` = no dithering, `1` = full dithering. Default: `0`
80
80
  */
81
81
  ditherStrength: number;
82
+ /**
83
+ * Assumed aspect ratio (width ÷ height) of a single output character.
84
+ * Controls how many rows vs columns are generated — must match your rendering
85
+ * environment to preserve the source image's proportions.
86
+ * - `0.55` — browser monospace at `line-height: 1.09` (default)
87
+ * - `0.52` — browser monospace at `line-height: 1.15`
88
+ * - `0.5` — most terminal emulators
89
+ * Default: `0.55`
90
+ */
91
+ charAspect: number;
92
+ /**
93
+ * Auto-stretch the luminance range before charset mapping.
94
+ * When `true`, the darkest pixel in the frame maps to the first charset character
95
+ * and the brightest to the last, maximising perceived detail and contrast.
96
+ * Particularly useful for images with low inherent contrast or muted tones.
97
+ * Default: `false`
98
+ */
99
+ normalize: boolean;
82
100
  /**
83
101
  * Overall intensity of the hover / cursor interaction effect.
84
102
  * `0` disables the effect. Default: `0`
package/dist/index.d.ts CHANGED
@@ -79,6 +79,24 @@ interface AsciiOptions {
79
79
  * `0` = no dithering, `1` = full dithering. Default: `0`
80
80
  */
81
81
  ditherStrength: number;
82
+ /**
83
+ * Assumed aspect ratio (width ÷ height) of a single output character.
84
+ * Controls how many rows vs columns are generated — must match your rendering
85
+ * environment to preserve the source image's proportions.
86
+ * - `0.55` — browser monospace at `line-height: 1.09` (default)
87
+ * - `0.52` — browser monospace at `line-height: 1.15`
88
+ * - `0.5` — most terminal emulators
89
+ * Default: `0.55`
90
+ */
91
+ charAspect: number;
92
+ /**
93
+ * Auto-stretch the luminance range before charset mapping.
94
+ * When `true`, the darkest pixel in the frame maps to the first charset character
95
+ * and the brightest to the last, maximising perceived detail and contrast.
96
+ * Particularly useful for images with low inherent contrast or muted tones.
97
+ * Default: `false`
98
+ */
99
+ normalize: boolean;
82
100
  /**
83
101
  * Overall intensity of the hover / cursor interaction effect.
84
102
  * `0` disables the effect. Default: `0`
package/dist/index.js CHANGED
@@ -110,6 +110,8 @@ var DEFAULT_OPTIONS = {
110
110
  animationSpeed: 1,
111
111
  dotSizeRatio: 0.8,
112
112
  ditherStrength: 0,
113
+ charAspect: 0.55,
114
+ normalize: false,
113
115
  hoverStrength: 0,
114
116
  hoverRadius: 0.2,
115
117
  hoverEffect: "spotlight",
@@ -604,7 +606,7 @@ function imageToAsciiFrame(source, options, targetWidth, targetHeight) {
604
606
  if (srcWidth === 0 || srcHeight === 0) {
605
607
  return { frame: [], cols: 0, rows: 0 };
606
608
  }
607
- const charAspect = 0.55;
609
+ const charAspect = options.charAspect;
608
610
  const cellW = options.fontSize * options.charSpacing;
609
611
  const cellH = options.fontSize / charAspect * options.charSpacing;
610
612
  const renderW = targetWidth || srcWidth;
@@ -618,6 +620,18 @@ function imageToAsciiFrame(source, options, targetWidth, targetHeight) {
618
620
  ctx.drawImage(source, 0, 0, cols, rows);
619
621
  const imageData = ctx.getImageData(0, 0, cols, rows);
620
622
  const pixels = imageData.data;
623
+ let normMin = 0;
624
+ let normRange = 255;
625
+ if (options.normalize) {
626
+ let lo = 255, hi = 0;
627
+ for (let k = 0; k < pixels.length; k += 4) {
628
+ const l = 0.299 * pixels[k] + 0.587 * pixels[k + 1] + 0.114 * pixels[k + 2];
629
+ if (l < lo) lo = l;
630
+ if (l > hi) hi = l;
631
+ }
632
+ normMin = lo;
633
+ normRange = hi > lo ? hi - lo : 255;
634
+ }
621
635
  const frame = [];
622
636
  for (let y = 0; y < rows; y++) {
623
637
  const row = [];
@@ -627,7 +641,8 @@ function imageToAsciiFrame(source, options, targetWidth, targetHeight) {
627
641
  const g = pixels[i + 1];
628
642
  const b = pixels[i + 2];
629
643
  const a = pixels[i + 3];
630
- const lum = 0.299 * r + 0.587 * g + 0.114 * b;
644
+ const rawLum = 0.299 * r + 0.587 * g + 0.114 * b;
645
+ const lum = options.normalize ? (rawLum - normMin) / normRange * 255 : rawLum;
631
646
  const adjustedLum = adjustLuminance(lum, options.brightness, options.contrast);
632
647
  const ditheredLum = applyDither(adjustedLum, x, y, options.ditherStrength);
633
648
  const char = options.customText ? customTextToChar(ditheredLum, options.customText, x, y, cols, options.invert) : luminanceToChar(ditheredLum, options.charset, options.invert);