diff --git a/Javascript/Real-Time Filter Camera/README.md b/Javascript/Real-Time Filter Camera/README.md
new file mode 100644
index 0000000..0087230
--- /dev/null
+++ b/Javascript/Real-Time Filter Camera/README.md
@@ -0,0 +1,12 @@
+# 🎥 Live Webcam Filters
+
+A real-time webcam filter application built with HTML5 Canvas and vanilla JavaScript. Apply fun visual effects to your webcam feed directly in the browser!
+
+## ✨ Features
+ - 🎨 Normal (no filter)
+ - ⚫ Grayscale (black & white)
+ - 🟤 Sepia (vintage photo)
+ - 🔄 Invert (negative colors)
+ - 🌫️ Blur (soft focus)
+ - ☀️ Brightness (enhanced lighting)
+ - 🎭 Contrast (dramatic tones)
diff --git a/Javascript/Real-Time Filter Camera/index.html b/Javascript/Real-Time Filter Camera/index.html
new file mode 100644
index 0000000..db4995b
--- /dev/null
+++ b/Javascript/Real-Time Filter Camera/index.html
@@ -0,0 +1,38 @@
+
+
+
+
+
+ Webcam Filters
+
+
+
+
+
🎥 Live Webcam Filters
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Click "Start Webcam" to begin
+
Current Filter: Normal
+
+
+
+
+
+
diff --git a/Javascript/Real-Time Filter Camera/script.js b/Javascript/Real-Time Filter Camera/script.js
new file mode 100644
index 0000000..6eb9747
--- /dev/null
+++ b/Javascript/Real-Time Filter Camera/script.js
@@ -0,0 +1,137 @@
+const video = document.getElementById('video');
+const canvas = document.getElementById('canvas');
+const ctx = canvas.getContext('2d', { willReadFrequently: true });
+const startBtn = document.getElementById('startBtn');
+const filterBtns = document.querySelectorAll('.filter-btn');
+const status = document.getElementById('status');
+const filterLabel = document.getElementById('filterLabel');
+
+let currentFilter = 'none';
+let stream = null;
+let animationId = null;
+let isWebcamActive = false;
+
+startBtn.addEventListener('click', async () => {
+ if (isWebcamActive) {
+ stopWebcam();
+ return;
+ }
+
+ try {
+ stream = await navigator.mediaDevices.getUserMedia({
+ video: { width: 640, height: 480 }
+ });
+ video.srcObject = stream;
+
+ video.addEventListener('loadedmetadata', () => {
+ canvas.width = video.videoWidth;
+ canvas.height = video.videoHeight;
+ startBtn.textContent = 'Stop Webcam';
+ startBtn.style.background = 'linear-gradient(135deg, #f093fb 0%, #f5576c 100%)';
+ status.textContent = 'Webcam active! Select a filter below';
+ isWebcamActive = true;
+ applyFilter();
+ });
+ } catch (err) {
+ status.textContent = 'Error: Could not access webcam';
+ console.error('Webcam error:', err);
+ }
+});
+
+function stopWebcam() {
+ if (stream) {
+ stream.getTracks().forEach(track => track.stop());
+ stream = null;
+ }
+ if (animationId) {
+ cancelAnimationFrame(animationId);
+ animationId = null;
+ }
+ video.srcObject = null;
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
+ startBtn.textContent = 'Start Webcam';
+ startBtn.style.background = 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)';
+ status.textContent = 'Webcam stopped. Click to restart';
+ isWebcamActive = false;
+}
+
+filterBtns.forEach(btn => {
+ btn.addEventListener('click', () => {
+ filterBtns.forEach(b => b.classList.remove('active'));
+ btn.classList.add('active');
+ currentFilter = btn.dataset.filter;
+ const filterName = btn.textContent;
+ filterLabel.textContent = `Current Filter: ${filterName}`;
+ });
+});
+
+function applyFilter() {
+ if (!video.paused && !video.ended) {
+ ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
+
+ if (currentFilter !== 'none') {
+ const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
+ const data = imageData.data;
+
+ switch(currentFilter) {
+ case 'grayscale':
+ for (let i = 0; i < data.length; i += 4) {
+ const avg = (data[i] + data[i + 1] + data[i + 2]) / 3;
+ data[i] = avg;
+ data[i + 1] = avg;
+ data[i + 2] = avg;
+ }
+ break;
+
+ case 'sepia':
+ for (let i = 0; i < data.length; i += 4) {
+ const r = data[i];
+ const g = data[i + 1];
+ const b = data[i + 2];
+ data[i] = Math.min(255, (r * 0.393) + (g * 0.769) + (b * 0.189));
+ data[i + 1] = Math.min(255, (r * 0.349) + (g * 0.686) + (b * 0.168));
+ data[i + 2] = Math.min(255, (r * 0.272) + (g * 0.534) + (b * 0.131));
+ }
+ break;
+
+ case 'invert':
+ for (let i = 0; i < data.length; i += 4) {
+ data[i] = 255 - data[i];
+ data[i + 1] = 255 - data[i + 1];
+ data[i + 2] = 255 - data[i + 2];
+ }
+ break;
+
+ case 'blur':
+ ctx.filter = 'blur(4px)';
+ ctx.drawImage(canvas, 0, 0);
+ ctx.filter = 'none';
+ break;
+
+ case 'brightness':
+ for (let i = 0; i < data.length; i += 4) {
+ data[i] = Math.min(255, data[i] * 1.5);
+ data[i + 1] = Math.min(255, data[i + 1] * 1.5);
+ data[i + 2] = Math.min(255, data[i + 2] * 1.5);
+ }
+ break;
+
+ case 'contrast':
+ const factor = 1.5;
+ const intercept = 128 * (1 - factor);
+ for (let i = 0; i < data.length; i += 4) {
+ data[i] = Math.min(255, Math.max(0, data[i] * factor + intercept));
+ data[i + 1] = Math.min(255, Math.max(0, data[i + 1] * factor + intercept));
+ data[i + 2] = Math.min(255, Math.max(0, data[i + 2] * factor + intercept));
+ }
+ break;
+ }
+
+ if (currentFilter !== 'blur') {
+ ctx.putImageData(imageData, 0, 0);
+ }
+ }
+
+ animationId = requestAnimationFrame(applyFilter);
+ }
+}
\ No newline at end of file
diff --git a/Javascript/Real-Time Filter Camera/styles.css b/Javascript/Real-Time Filter Camera/styles.css
new file mode 100644
index 0000000..bf58c53
--- /dev/null
+++ b/Javascript/Real-Time Filter Camera/styles.css
@@ -0,0 +1,125 @@
+* {
+ margin: 0;
+ padding: 0;
+ box-sizing: border-box;
+}
+
+body {
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
+ background: linear-gradient(180deg, #070507 0%, #1a50b3 100%);
+ min-height: 100vh;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ padding: 20px;
+}
+
+.container {
+ background: linear-gradient(180deg, #f9a425e5 0%, #c71b1b 100%);
+ border-radius: 20px;
+ padding: 30px;
+ box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
+ max-width: 900px;
+ width: 100%;
+}
+
+h1 {
+ text-align: center;
+ color: #333;
+ margin-bottom: 25px;
+ font-size: 2em;
+}
+
+.video-container {
+ position: relative;
+ width: 100%;
+ max-width: 640px;
+ margin: 0 auto 25px;
+ border-radius: 15px;
+ overflow: hidden;
+ box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
+}
+
+#video {
+ display: none;
+}
+
+#canvas {
+ width: 100%;
+ height: auto;
+ display: block;
+ background: #000;
+}
+
+.controls {
+ display: flex;
+ flex-direction: column;
+ gap: 15px;
+}
+
+.button-group {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 10px;
+ justify-content: center;
+}
+
+button {
+ padding: 12px 24px;
+ font-size: 16px;
+ font-weight: 600;
+ border: none;
+ border-radius: 10px;
+ cursor: pointer;
+ transition: all 0.3s ease;
+ color: white;
+ text-transform: uppercase;
+ letter-spacing: 0.5px;
+}
+
+#startBtn {
+ background: linear-gradient(135deg, #4877f9 0%, #50158f 100%);
+}
+
+#startBtn:hover {
+ transform: translateY(-2px);
+ box-shadow: 0 5px 15px rgba(102, 126, 234, 0.4);
+}
+
+.filter-btn {
+ background: linear-gradient(135deg, #f093fb 0%, #bbe1b8 100%);
+ min-width: 120px;
+}
+
+.filter-btn:hover {
+ transform: translateY(-2px);
+ box-shadow: 0 5px 15px rgba(245, 87, 108, 0.4);
+}
+
+.filter-btn.active {
+ background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
+ box-shadow: 0 0 20px rgba(79, 172, 254, 0.5);
+}
+
+button:disabled {
+ opacity: 0.5;
+ cursor: not-allowed;
+ transform: none !important;
+}
+
+.status {
+ text-align: center;
+ padding: 15px;
+ border-radius: 10px;
+ background: linear-gradient(135deg, #f1f1f0 0%, #faf7f6 100%);
+ color: #333;
+ font-weight: 500;
+}
+
+.filter-label {
+ text-align: center;
+ font-size: 14px;
+ color: #f8f5f5;
+ margin-top: 10px;
+}
\ No newline at end of file