<div class="container">
<h1>Blogger Image Compressor</h1>
<div class="tool-container">
<div class="input-section">
<input type="file" id="uploadInput" accept="image/*" />
<label for="uploadInput" class="upload-btn">Choose Image</label>
<div class="settings">
<label>Max Width: <input type="number" id="maxWidth" value="800" min="100"></label>
<label>Max Height: <input type="number" id="maxHeight" value="800" min="100"></label>
<label>Quality (0-1): <input type="number" id="quality" value="0.8" step="0.1" min="0.1" max="1"></label>
</div>
</div>
<div class="preview-section">
<div id="originalInfo"></div>
<div id="compressedInfo"></div>
<div class="image-container">
<img id="previewImage" />
</div>
<button id="downloadBtn" disabled>Download Compressed Image</button>
</div>
</div>
<div class="loading" id="loading">Processing...</div>
</div>
<style>
.container {
max-width: 800px;
margin: 20px auto;
padding: 20px;
font-family: Arial, sans-serif;
}
.tool-container {
border: 1px solid #ddd;
padding: 20px;
border-radius: 8px;
}
.input-section {
margin-bottom: 20px;
}
.upload-btn {
background: #4285f4;
color: white;
padding: 10px 20px;
border-radius: 4px;
cursor: pointer;
display: inline-block;
margin-bottom: 15px;
}
.settings {
display: flex;
gap: 15px;
flex-wrap: wrap;
margin-top: 15px;
}
.settings label {
display: flex;
align-items: center;
gap: 5px;
}
.settings input[type="number"] {
width: 80px;
padding: 5px;
}
.preview-section {
margin-top: 20px;
}
.image-container {
margin: 15px 0;
text-align: center;
}
#previewImage {
max-width: 100%;
height: auto;
border: 1px solid #ddd;
}
#downloadBtn {
background: #34a853;
color: white;
padding: 10px 25px;
border: none;
border-radius: 4px;
cursor: pointer;
}
#downloadBtn:disabled {
background: #ccc;
cursor: not-allowed;
}
.loading {
display: none;
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(255,255,255,0.8);
justify-content: center;
align-items: center;
font-size: 1.2em;
}
</style>
<script>
const MAX_WIDTH = document.getElementById('maxWidth');
const MAX_HEIGHT = document.getElementById('maxHeight');
const QUALITY = document.getElementById('quality');
const UPLOAD_INPUT = document.getElementById('uploadInput');
const PREVIEW_IMAGE = document.getElementById('previewImage');
const DOWNLOAD_BTN = document.getElementById('downloadBtn');
const LOADING = document.getElementById('loading');
const ORIGINAL_INFO = document.getElementById('originalInfo');
const COMPRESSED_INFO = document.getElementById('compressedInfo');
let currentCompressedBlob = null;
function compressImage(file) {
LOADING.style.display = 'flex';
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = function(event) {
const img = new Image();
img.src = event.target.result;
img.onload = function() {
const canvas = document.createElement('canvas');
let width = img.width;
let height = img.height;
// Calculate new dimensions
if (width > MAX_WIDTH.value) {
height = height * (MAX_WIDTH.value / width);
width = MAX_WIDTH.value;
}
if (height > MAX_HEIGHT.value) {
width = width * (MAX_HEIGHT.value / height);
height = MAX_HEIGHT.value;
}
canvas.width = width;
canvas.height = height;
const ctx = canvas.getContext('2d');
ctx.drawImage(img, 0, 0, width, height);
// Show original info
ORIGINAL_INFO.innerHTML = `Original Size: ${formatBytes(file.size)}`;
// Convert to compressed JPEG
canvas.toBlob((blob) => {
currentCompressedBlob = blob;
PREVIEW_IMAGE.src = URL.createObjectURL(blob);
COMPRESSED_INFO.innerHTML = `Compressed Size: ${formatBytes(blob.size)}
(${((1 - blob.size/file.size) * 100).toFixed(1)}% reduction)`;
DOWNLOAD_BTN.disabled = false;
LOADING.style.display = 'none';
}, 'image/jpeg', QUALITY.value);
};
};
}
function formatBytes(bytes) {
if (bytes === 0) return '0 Bytes';
const k = 1024;
const sizes = ['Bytes', 'KB', 'MB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
}
// Event Listeners
UPLOAD_INPUT.addEventListener('change', function(e) {
if (e.target.files.length === 0) return;
const file = e.target.files[0];
if (!file.type.startsWith('image/')) {
alert('Please select an image file');
return;
}
compressImage(file);
});
DOWNLOAD_BTN.addEventListener('click', function() {
if (!currentCompressedBlob) return;
const link = document.createElement('a');
link.download = `compressed_${UPLOAD_INPUT.files[0].name.replace(/\..+$/, '.jpg')}`;
link.href = URL.createObjectURL(currentCompressedBlob);
link.click();
});
// Update compression when settings change
[MAX_WIDTH, MAX_HEIGHT, QUALITY].forEach(input => {
input.addEventListener('change', () => {
if (UPLOAD_INPUT.files.length > 0) {
compressImage(UPLOAD_INPUT.files[0]);
}
});
});
</script>