<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Image Compressor</title>
<style>
* {
box-sizing: border-box;
margin: 0;
padding: 0;
font-family: Arial, sans-serif;
}
body {
background: #f0f2f5;
min-height: 100vh;
padding: 2rem;
}
.container {
max-width: 800px;
margin: 0 auto;
background: white;
padding: 2rem;
border-radius: 10px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}
h1 {
text-align: center;
color: #333;
margin-bottom: 2rem;
}
.upload-section {
border: 2px dashed #ccc;
padding: 2rem;
text-align: center;
margin-bottom: 2rem;
cursor: pointer;
transition: border-color 0.3s;
}
.upload-section:hover {
border-color: #2196F3;
}
#preview {
max-width: 100%;
margin: 1rem 0;
display: none;
}
.controls {
margin: 2rem 0;
}
.quality-slider {
width: 100%;
margin: 1rem 0;
}
button {
background: #2196F3;
color: white;
border: none;
padding: 0.8rem 1.5rem;
border-radius: 5px;
cursor: pointer;
font-size: 1rem;
transition: background 0.3s;
}
button:hover {
background: #1976D2;
}
.results {
margin-top: 2rem;
display: none;
}
.comparison {
display: flex;
gap: 1rem;
margin: 1rem 0;
}
.comparison img {
max-width: 48%;
border: 1px solid #ddd;
border-radius: 5px;
}
.file-info {
margin: 1rem 0;
padding: 1rem;
background: #f8f9fa;
border-radius: 5px;
}
</style>
</head>
<body>
<div class="container">
<h1>Image Compressor</h1>
<div class="upload-section" onclick="document.getElementById('fileInput').click()">
<p>Click to upload or drag and drop image</p>
<input type="file" id="fileInput" hidden accept="image/*">
<img id="preview" alt="Preview">
</div>
<div class="controls">
<label>Compression Quality: <span id="qualityValue">80</span>%</label>
<input type="range" class="quality-slider" id="quality" min="1" max="100" value="80">
<button onclick="compressImage()">Compress Image</button>
</div>
<div class="results" id="results">
<div class="comparison">
<div>
<h3>Original</h3>
<img id="originalPreview" alt="Original">
</div>
<div>
<h3>Compressed</h3>
<img id="compressedPreview" alt="Compressed">
</div>
</div>
<div class="file-info">
<p>Original Size: <span id="originalSize"></span></p>
<p>Compressed Size: <span id="compressedSize"></span></p>
<p>Reduction: <span id="reduction"></span></p>
</div>
<button id="downloadBtn" style="display: none;">Download Compressed Image</button>
</div>
</div>
<script>
let originalFile = null;
let compressedBlob = null;
const qualitySlider = document.getElementById('quality');
const qualityValue = document.getElementById('qualityValue');
// Handle file selection
document.getElementById('fileInput').addEventListener('change', function(e) {
const file = e.target.files[0];
if (!file.type.startsWith('image/')) {
alert('Please select an image file');
return;
}
originalFile = file;
const reader = new FileReader();
reader.onload = function(e) {
const preview = document.getElementById('preview');
preview.src = e.target.result;
preview.style.display = 'block';
document.getElementById('originalPreview').src = e.target.result;
document.getElementById('originalSize').textContent = formatBytes(file.size);
};
reader.readAsDataURL(file);
document.getElementById('results').style.display = 'block';
});
// Handle quality slider
qualitySlider.addEventListener('input', function() {
qualityValue.textContent = this.value;
});
// Compression function
function compressImage() {
if (!originalFile) {
alert('Please select an image first');
return;
}
const quality = qualitySlider.value / 100;
const img = new Image();
img.onload = function() {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
// Set canvas dimensions
canvas.width = img.width;
canvas.height = img.height;
// Draw image on canvas
ctx.drawImage(img, 0, 0);
// Convert to compressed JPEG
canvas.toBlob(function(blob) {
compressedBlob = blob;
// Update UI
document.getElementById('compressedPreview').src = URL.createObjectURL(blob);
document.getElementById('compressedSize').textContent = formatBytes(blob.size);
document.getElementById('reduction').textContent =
`${Math.round((1 - blob.size/originalFile.size) * 100)}% smaller`;
// Show download button
const downloadBtn = document.getElementById('downloadBtn');
downloadBtn.style.display = 'inline-block';
downloadBtn.onclick = function() {
const link = document.createElement('a');
link.download = `compressed_${originalFile.name}`;
link.href = URL.createObjectURL(blob);
link.click();
};
}, 'image/jpeg', quality);
};
img.src = URL.createObjectURL(originalFile);
}
// Helper function to format bytes
function formatBytes(bytes) {
if (bytes === 0) return '0 Bytes';
const k = 1024;
const sizes = ['Bytes', 'KB', 'MB', 'GB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(2) + ' ' + sizes[i];
}
// Drag and drop handling
const uploadSection = document.querySelector('.upload-section');
uploadSection.addEventListener('dragover', (e) => {
e.preventDefault();
uploadSection.style.borderColor = '#2196F3';
});
uploadSection.addEventListener('dragleave', () => {
uploadSection.style.borderColor = '#ccc';
});
uploadSection.addEventListener('drop', (e) => {
e.preventDefault();
uploadSection.style.borderColor = '#ccc';
const file = e.dataTransfer.files[0];
if (file.type.startsWith('image/')) {
document.getElementById('fileInput').files = e.dataTransfer.files;
document.getElementById('fileInput').dispatchEvent(new Event('change'));
}
});
</script>
</body>
</html>