asciify-engine 1.0.63 → 1.0.65

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.cjs CHANGED
@@ -726,9 +726,14 @@ function imageToAsciiFrame(source, options, targetWidth, targetHeight) {
726
726
  if (cols <= 0 || rows <= 0) {
727
727
  return { frame: [], cols: 0, rows: 0 };
728
728
  }
729
- const { ctx } = createOffscreenCanvas(cols, rows);
730
- ctx.drawImage(source, 0, 0, cols, rows);
731
- const imageData = ctx.getImageData(0, 0, cols, rows);
729
+ const maxDim = 2048;
730
+ const ssX = Math.max(1, Math.min(Math.floor(maxDim / cols), Math.floor(srcWidth / cols)));
731
+ const ssY = Math.max(1, Math.min(Math.floor(maxDim / rows), Math.floor(srcHeight / rows)));
732
+ const sampleW = cols * ssX;
733
+ const sampleH = rows * ssY;
734
+ const { ctx } = createOffscreenCanvas(sampleW, sampleH);
735
+ ctx.drawImage(source, 0, 0, sampleW, sampleH);
736
+ const imageData = ctx.getImageData(0, 0, sampleW, sampleH);
732
737
  const pixels = imageData.data;
733
738
  const ck = options.chromaKey;
734
739
  const ckEnabled = ck != null && ck !== false;
@@ -768,31 +773,47 @@ function imageToAsciiFrame(source, options, targetWidth, targetHeight) {
768
773
  const frame = [];
769
774
  const invertVal = resolveInvert(options.invert);
770
775
  const effectiveCharset = ckEnabled ? options.charset.replace(/ /g, "") || options.charset : options.charset;
776
+ const ssCount = ssX * ssY;
771
777
  for (let y = 0; y < rows; y++) {
772
778
  const row = [];
773
779
  for (let x = 0; x < cols; x++) {
774
- const i = (y * cols + x) * 4;
775
- const r = pixels[i];
776
- const g = pixels[i + 1];
777
- const b = pixels[i + 2];
778
- const a = pixels[i + 3];
779
- if (ckEnabled) {
780
- let keyed = false;
781
- if (ckHeuristicGreen) {
782
- keyed = g > r * 1.4 && g > b * 1.4 && g > 80;
783
- } else if (ckHeuristicBlue) {
784
- keyed = b > r * 1.4 && b > g * 1.4 && b > 80;
785
- } else if (ckRGB !== null) {
786
- const dr = r - ckRGB.r;
787
- const dg = g - ckRGB.g;
788
- const db = b - ckRGB.b;
789
- keyed = dr * dr + dg * dg + db * db <= ckTolSq;
790
- }
791
- if (keyed) {
792
- row.push({ char: " ", r: 0, g: 0, b: 0, a: 0 });
793
- continue;
780
+ let sumR = 0, sumG = 0, sumB = 0, sumA = 0;
781
+ let keyedCount = 0;
782
+ for (let sy = 0; sy < ssY; sy++) {
783
+ const rowOff = (y * ssY + sy) * sampleW;
784
+ for (let sx = 0; sx < ssX; sx++) {
785
+ const i = (rowOff + x * ssX + sx) * 4;
786
+ const pr = pixels[i], pg = pixels[i + 1], pb = pixels[i + 2], pa = pixels[i + 3];
787
+ if (ckEnabled) {
788
+ let keyed = false;
789
+ if (ckHeuristicGreen) {
790
+ keyed = pg > pr * 1.4 && pg > pb * 1.4 && pg > 80;
791
+ } else if (ckHeuristicBlue) {
792
+ keyed = pb > pr * 1.4 && pb > pg * 1.4 && pb > 80;
793
+ } else if (ckRGB !== null) {
794
+ const dr = pr - ckRGB.r, dg = pg - ckRGB.g, db = pb - ckRGB.b;
795
+ keyed = dr * dr + dg * dg + db * db <= ckTolSq;
796
+ }
797
+ if (keyed) {
798
+ keyedCount++;
799
+ continue;
800
+ }
801
+ }
802
+ sumR += pr;
803
+ sumG += pg;
804
+ sumB += pb;
805
+ sumA += pa;
794
806
  }
795
807
  }
808
+ if (ckEnabled && keyedCount > ssCount / 2) {
809
+ row.push({ char: " ", r: 0, g: 0, b: 0, a: 0 });
810
+ continue;
811
+ }
812
+ const nonKeyed = ssCount - keyedCount;
813
+ const r = nonKeyed > 0 ? sumR / nonKeyed : 0;
814
+ const g = nonKeyed > 0 ? sumG / nonKeyed : 0;
815
+ const b = nonKeyed > 0 ? sumB / nonKeyed : 0;
816
+ const a = nonKeyed > 0 ? sumA / nonKeyed : 0;
796
817
  const rawLum = 0.299 * r + 0.587 * g + 0.114 * b;
797
818
  const lum = options.normalize ? (rawLum - normMin) / normRange * 255 : rawLum;
798
819
  const adjustedLum = adjustLuminance(lum, options.brightness, options.contrast);
@@ -1149,8 +1170,13 @@ function sizeCanvasToContainer(canvas, container, aspect) {
1149
1170
  h = height;
1150
1171
  w = h * aspect;
1151
1172
  }
1152
- canvas.width = Math.round(w);
1153
- canvas.height = Math.round(h);
1173
+ const dpr = typeof window !== "undefined" ? window.devicePixelRatio || 1 : 1;
1174
+ const cssW = Math.round(w);
1175
+ const cssH = Math.round(h);
1176
+ canvas.width = Math.round(cssW * dpr);
1177
+ canvas.height = Math.round(cssH * dpr);
1178
+ canvas.style.width = cssW + "px";
1179
+ canvas.style.height = cssH + "px";
1154
1180
  }
1155
1181
  async function asciify(source, canvas, { fontSize = 10, artStyle = "classic", options = {} } = {}) {
1156
1182
  let el;