asciify-engine 1.0.63 → 1.0.64
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 +44 -23
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +44 -23
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
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
|
|
730
|
-
|
|
731
|
-
const
|
|
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
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
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);
|