about summary refs log tree commit diff stats
path: root/js/lut-cam/lut.js
diff options
context:
space:
mode:
authorelioat <elioat@tilde.institute>2024-08-14 22:24:17 -0400
committerelioat <elioat@tilde.institute>2024-08-14 22:24:17 -0400
commit91851865712e188650ea11a046c8de2c22674548 (patch)
treeedbc32992d5561a1851848e3fe829125ddf32a1a /js/lut-cam/lut.js
parent391793456f87ccba1a8e1775e1695ced9594ae33 (diff)
downloadtour-91851865712e188650ea11a046c8de2c22674548.tar.gz
*
Diffstat (limited to 'js/lut-cam/lut.js')
-rw-r--r--js/lut-cam/lut.js128
1 files changed, 128 insertions, 0 deletions
diff --git a/js/lut-cam/lut.js b/js/lut-cam/lut.js
new file mode 100644
index 0000000..6466f32
--- /dev/null
+++ b/js/lut-cam/lut.js
@@ -0,0 +1,128 @@
+const canvas = document.getElementById('canvas');
+const ctx = canvas.getContext('2d');
+const video = document.createElement('video');
+const toggleCameraButton = document.getElementById('toggle-camera');
+const lutSelect = document.getElementById('lut-select');
+const captureButton = document.getElementById('capture');
+
+let cameraOn = false;
+let stream = null;
+
+// Set the canvas dimensions to match the window size
+canvas.width = window.innerWidth;
+canvas.height = window.innerHeight;
+
+const LUTs = {
+    'none': null,
+    'lut1': (r, g, b) => [255 - r, 255 - g, 255 - b], // Inverted Colors
+    'lut2': (r, g, b) => [r * 1.2, g * 0.8, b * 1.5], // Enhanced Colors
+    'lut3': (r, g, b) => [r * 0.9, g * 0.9, b * 1.1], // Subtle Cool Tone
+    'lut4': (r, g, b) => [r * 1.1, g * 0.9, b * 0.9], // Subtle Warm Tone
+    'lut5': (r, g, b) => [r * 0.9, g * 1.1, b * 0.9], // Subtle Green Tone
+    'lut6': (r, g, b) => [r * 1.1, g * 1.1, b * 0.9], // Subtle Yellow Tone
+    'lut7': (r, g, b) => [r * 0.9, g * 0.9, b * 0.9], // Desaturated
+    'lut8': (r, g, b) => [r * 1.1, g * 1.1, b * 1.1], // Saturated
+    'lut9': (r, g, b) => [r * 0.9, g * 1.1, b * 1.1], // Warm Tint
+    'lut10': (r, g, b) => [r * 1.1, g * 0.9, b * 0.9], // Cool Tint
+    'lut11': (r, g, b) => { const avg = (r + g + b) / 3; return [avg, avg, avg]; }, // Greyscale
+    'lut12': (r, g, b) => { const avg = (r + g + b) / 3; return [avg * 1.1, avg * 0.9, avg * 0.9]; } // Sepia
+};
+
+let currentLUT = null;
+
+function startCamera() {
+    navigator.mediaDevices.getUserMedia({ video: { facingMode: { ideal: 'environment' } } })
+        .then(s => {
+            stream = s;
+            video.srcObject = stream;
+            video.play();
+            canvas.style.display = 'block'; // Show the canvas
+            lutSelect.disabled = false;
+            captureButton.disabled = false;
+
+            // Display the video feed on the canvas
+            video.addEventListener('play', function() {
+                function step() {
+                    if (!cameraOn) return; // Don't show the video feed if there isn't a video feed to show
+                    drawVideoProportional();
+                    applyLUT();
+                    requestAnimationFrame(step);
+                }
+                requestAnimationFrame(step);
+            });
+        })
+        .catch(err => {
+            console.error('Error accessing camera: ', err);
+        });
+}
+
+function stopCamera() {
+    if (stream) {
+        stream.getTracks().forEach(track => track.stop());
+        video.pause();
+        canvas.style.display = 'none';
+        lutSelect.disabled = true;
+        captureButton.disabled = true;
+        stream = null;
+    }
+}
+
+function drawVideoProportional() {
+    const videoAspectRatio = video.videoWidth / video.videoHeight;
+    const canvasAspectRatio = canvas.width / canvas.height;
+
+    let drawWidth, drawHeight;
+
+    if (canvasAspectRatio > videoAspectRatio) {
+        drawHeight = canvas.height;
+        drawWidth = videoAspectRatio * drawHeight;
+    } else {
+        drawWidth = canvas.width;
+        drawHeight = drawWidth / videoAspectRatio;
+    }
+
+    const offsetX = (canvas.width - drawWidth) / 2;
+    const offsetY = (canvas.height - drawHeight) / 2;
+
+    ctx.clearRect(0, 0, canvas.width, canvas.height); // Clear the canvas
+    ctx.drawImage(video, offsetX, offsetY, drawWidth, drawHeight); // Draw the video normally
+}
+
+function applyLUT() {
+    if (!currentLUT) return;
+
+    const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
+    const data = imageData.data;
+
+    for (let i = 0; i < data.length; i += 4) {
+        const [r, g, b] = currentLUT(data[i], data[i + 1], data[i + 2]);
+        data[i] = r;
+        data[i + 1] = g;
+        data[i + 2] = b;
+    }
+
+    ctx.putImageData(imageData, 0, 0);
+}
+
+toggleCameraButton.addEventListener('click', () => {
+    cameraOn = !cameraOn;
+    if (cameraOn) {
+        startCamera();
+        toggleCameraButton.textContent = 'Turn Camera Off';
+    } else {
+        stopCamera();
+        toggleCameraButton.textContent = 'Turn Camera On';
+    }
+});
+
+lutSelect.addEventListener('change', () => {
+    const selectedLUT = lutSelect.value;
+    currentLUT = LUTs[selectedLUT];
+});
+
+captureButton.addEventListener('click', () => {
+    const link = document.createElement('a');
+    link.download = 'captured-image.png';
+    link.href = canvas.toDataURL('image/png');
+    link.click();
+});