// script.js const imageLoader = document.getElementById(‘imageLoader’); const originalImage = document.getElementById(‘originalImage’); const canvas = document.getElementById(‘imageCanvas’); const ctx = canvas.getContext(‘2d’); let img = new Image(); let originalImageData; // Almacena los datos de píxeles de la imagen original // Cargar imagen imageLoader.addEventListener(‘change’, (e) => { const reader = new FileReader(); reader.onload = (event) => { img.onload = () => { // Ajustar el tamaño del canvas al tamaño de la imagen canvas.width = img.width; canvas.height = img.height; ctx.drawImage(img, 0, 0); originalImageData = ctx.getImageData(0, 0, canvas.width, canvas.height); // Guardar datos originales }; img.src = event.target.result; }; reader.readAsDataURL(e.target.files[0]); }); // Función para aplicar filtros y redibujar function applyFilter() { if (!originalImageData) return; // No hay imagen cargada // Restablecer el canvas a la imagen original ctx.putImageData(originalImageData, 0, 0); let imageData = ctx.getImageData(0, 0, canvas.width, canvas.height); let data = imageData.data; // Aquí iría la lógica para los diferentes filtros // Ejemplo: Escala de Grises if (document.getElementById(‘grayscaleBtn’).classList.contains(‘active’)) { for (let i = 0; i < data.length; i += 4) { let avg = (data[i] + data[i + 1] + data[i + 2]) / 3; data[i] = avg; // Red data[i + 1] = avg; // Green data[i + 2] = avg; // Blue } } // Ejemplo: Sepia if (document.getElementById('sepiaBtn').classList.contains('active')) { for (let i = 0; i < data.length; i += 4) { let r = data[i]; let g = data[i + 1]; let b = data[i + 2]; data[i] = Math.min(255, (r * 0.393) + (g * 0.769) + (b * 0.189)); // Red data[i + 1] = Math.min(255, (r * 0.349) + (g * 0.686) + (b * 0.168)); // Green data[i + 2] = Math.min(255, (r * 0.272) + (g * 0.534) + (b * 0.131)); // Blue } } // Ejemplo: Invertir Colores if (document.getElementById('invertBtn').classList.contains('active')) { for (let i = 0; i < data.length; i += 4) { data[i] = 255 - data[i]; // Red data[i + 1] = 255 - data[i + 1]; // Green data[i + 2] = 255 - data[i + 2]; // Blue } } // Ejemplo: Brillo const brightness = parseInt(document.getElementById('brightnessSlider').value); if (brightness !== 100) { // Aplicar solo si no es el valor por defecto const factor = brightness / 100; for (let i = 0; i < data.length; i += 4) { data[i] = Math.min(255, data[i] * factor); data[i + 1] = Math.min(255, data[i + 1] * factor); data[i + 2] = Math.min(255, data[i + 2] * factor); } } ctx.putImageData(imageData, 0, 0); } // Event Listeners para los botones de filtro document.getElementById('grayscaleBtn').addEventListener('click', () => { document.getElementById(‘grayscaleBtn’).classList.toggle(‘active’); applyFilter(); }); document.getElementById(‘sepiaBtn’).addEventListener(‘click’, () => { document.getElementById(‘sepiaBtn’).classList.toggle(‘active’); applyFilter(); }); document.getElementById(‘invertBtn’).addEventListener(‘click’, () => { document.getElementById(‘invertBtn’).classList.toggle(‘active’); applyFilter(); }); // Event Listener para el slider de brillo document.getElementById(‘brightnessSlider’).addEventListener(‘input’, applyFilter); // Descargar imagen document.getElementById(‘downloadBtn’).addEventListener(‘click’, () => { if (!originalImageData) { alert(«Por favor, carga una imagen primero.»); return; } const dataURL = canvas.toDataURL(‘image/png’); // O ‘image/jpeg’ const a = document.createElement(‘a’); a.href = dataURL; a.download = ‘imagen_editada.png’; document.body.appendChild(a); a.click(); document.body.removeChild(a); }); // Estilo para los botones activos (opcional, pero mejora la UX) const filterButtons = document.querySelectorAll(‘.filters-panel button’); filterButtons.forEach(button => { button.addEventListener(‘click’, () => { button.classList.toggle(‘active’); // Alternar la clase ‘active’ }); });