From 91851865712e188650ea11a046c8de2c22674548 Mon Sep 17 00:00:00 2001 From: elioat Date: Wed, 14 Aug 2024 22:24:17 -0400 Subject: * --- js/lut-cam/index.html | 74 +++++++++++++++++++++++++++++ js/lut-cam/lut.js | 128 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 202 insertions(+) create mode 100644 js/lut-cam/index.html create mode 100644 js/lut-cam/lut.js (limited to 'js/lut-cam') diff --git a/js/lut-cam/index.html b/js/lut-cam/index.html new file mode 100644 index 0000000..f31c465 --- /dev/null +++ b/js/lut-cam/index.html @@ -0,0 +1,74 @@ + + + + + + LUT Cam + + + + + + +
+ +
+ +
+ + +
+ + + + 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(); +}); -- cgit 1.4.1-2-gfad0