about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorelioat <elioat@tilde.institute>2025-03-29 23:08:33 -0400
committerelioat <elioat@tilde.institute>2025-03-29 23:08:33 -0400
commitb3f0f9e478d450b9a1bf3a6278e1e3bdbe0f1f6f (patch)
treee14043b064d20d90a985cdc3b943ae08b785b869
parentf185a42a9f1f9431e6208bed6516737d92efefbd (diff)
downloadtour-b3f0f9e478d450b9a1bf3a6278e1e3bdbe0f1f6f.tar.gz
*
-rw-r--r--js/leibovitz/dither.js88
1 files changed, 74 insertions, 14 deletions
diff --git a/js/leibovitz/dither.js b/js/leibovitz/dither.js
index 9e1ffb1..90d6325 100644
--- a/js/leibovitz/dither.js
+++ b/js/leibovitz/dither.js
@@ -68,6 +68,8 @@ const DitherManager = {
                 return this._orderedDither(data, width, height);
             case 'atkinson':
                 return this._atkinsonDither(data, width, height);
+            case 'bayer':
+                return this._bayerDither(data, width, height);
             default:
                 return imageData;
         }
@@ -275,6 +277,72 @@ const DitherManager = {
         }
 
         return new ImageData(newData, width, height);
+    },
+
+    // Add this as a method in DitherManager
+    _bayerDither(data, width, height) {
+        const newData = new Uint8ClampedArray(data);
+        const blockSize = this.currentBlockSize;
+        
+        // 4x4 Bayer matrix (simpler and more visible pattern than 8x8)
+        const bayerMatrix = [
+            [ 0, 8, 2, 10],
+            [12, 4, 14, 6 ],
+            [ 3, 11, 1, 9 ],
+            [15, 7, 13, 5 ]
+        ];
+        
+        // Scale factor to make the pattern more pronounced
+        const scaleFactor = 16; // Increase this value to make pattern more visible
+        
+        // Process in blocks
+        for (let y = 0; y < height; y += blockSize) {
+            for (let x = 0; x < width; x += blockSize) {
+                // Calculate block average
+                let blockSum = [0, 0, 0];
+                let pixelCount = 0;
+                
+                for (let by = 0; by < blockSize && y + by < height; by++) {
+                    for (let bx = 0; bx < blockSize && x + bx < width; bx++) {
+                        const idx = ((y + by) * width + (x + bx)) * 4;
+                        for (let c = 0; c < 3; c++) {
+                            blockSum[c] += newData[idx + c];
+                        }
+                        pixelCount++;
+                    }
+                }
+
+                // Calculate block average
+                const blockAvg = blockSum.map(sum => sum / pixelCount);
+                
+                // Get matrix value for this block position
+                const matrixX = Math.floor(x / blockSize) % 4;
+                const matrixY = Math.floor(y / blockSize) % 4;
+                const threshold = (bayerMatrix[matrixY][matrixX] * scaleFactor);
+                
+                // Apply dithering to the block
+                for (let c = 0; c < 3; c++) {
+                    // Normalize pixel value and apply threshold
+                    const normalizedPixel = blockAvg[c];
+                    const newPixel = normalizedPixel > threshold ? 255 : 0;
+                    
+                    // Fill the entire block with the new color
+                    for (let by = 0; by < blockSize && y + by < height; by++) {
+                        for (let bx = 0; bx < blockSize && x + bx < width; bx++) {
+                            const idx = ((y + by) * width + (x + bx)) * 4;
+                            newData[idx + c] = newPixel;
+                        }
+                    }
+                }
+            }
+        }
+
+        // Preserve alpha channel
+        for (let i = 3; i < newData.length; i += 4) {
+            newData[i] = data[i];
+        }
+        
+        return new ImageData(newData, width, height);
     }
 };
 
@@ -337,25 +405,17 @@ function bayerDither(imageData, width) {
         }
     }
     
+    // Preserve alpha channel
+    for (let i = 3; i < data.length; i += 4) {
+        data[i] = imageData.data[i];
+    }
+    
     return data;
 }
 
 function applyDithering(imageData, width) {
     const method = document.getElementById('dither-select').value;
-    const blockSize = DitherManager.currentBlockSize;
-    
-    switch (method) {
-        case 'floyd-steinberg':
-            return DitherManager._floydSteinbergDither(imageData.data, width, imageData.height);
-        case 'bayer':
-            return bayerDither(imageData, width);
-        case 'atkinson':
-            return DitherManager._atkinsonDither(imageData.data, width, imageData.height);
-        case 'ordered':
-            return DitherManager._orderedDither(imageData.data, width, imageData.height);
-        default:
-            return new Uint8ClampedArray(imageData.data);
-    }
+    return DitherManager.applyDither(imageData, method);
 }
 
 function floydSteinbergDither(imageData, width, blockSize) {