Advanced Image Converter & Resizer
How to Use
Upload Images: Click the upload area or drag & drop one or more image files.
Set Options: Enter a base name, select the target format, and adjust dimensions or quality if needed.
Process: Click the “Process & Download” button.
Download: Each converted image will be saved directly to your device.
Features
✅ Batch Processing: Convert multiple images at once.
✅ Multiple Formats: Supports PNG, JPG, WEBP, GIF, BMP, and TIFF.
✅ Auto-Renaming: Rename files with automatic numbering.
✅ Image Resizing: Set custom width/height with aspect ratio lock.
✅ Quality Control: Adjust JPG/WEBP quality to optimize file size.
✅ Direct Downloads: Each image is saved individually.
';
return;
}
filesToProcess.forEach(item => {
const div = document.createElement('div');
div.className = 'img_file-item';
div.innerHTML = `
${item.file.name}
${item.originalSize}
Est. ...
×
`;
fileList.appendChild(div);
});
document.querySelectorAll('.img_remove-file-btn').forEach(button => {
button.addEventListener('click', (e) => {
const idToRemove = parseFloat(e.currentTarget.dataset.id);
filesToProcess = filesToProcess.filter(item => item.id !== idToRemove);
updateFileListUI();
});
});
updateAllEstimatedSizes();
}
function onSettingsChange() {
toggleQualitySlider();
clearTimeout(debounceTimer);
debounceTimer = setTimeout(() => {
updateAllEstimatedSizes();
}, 400); // Debounce to prevent rapid recalculations
}
function toggleQualitySlider() {
const selectedFormat = fileFormatSelect.value;
qualityControl.style.display = (selectedFormat === 'jpg' || selectedFormat === 'webp') ? 'block' : 'none';
}
async function updateAllEstimatedSizes() {
for (const item of filesToProcess) {
const sizeElement = document.querySelector(`.estimated-size[data-id="${item.id}"]`);
if (sizeElement) {
sizeElement.textContent = '...';
try {
const estimatedSize = await getEstimatedSize(item);
sizeElement.textContent = `Est. ${estimatedSize}`;
} catch (error) {
sizeElement.textContent = 'Error';
}
}
}
}
async function getEstimatedSize(item) {
const newFormat = fileFormatSelect.value;
const mimeType = `image/${newFormat}`;
const quality = qualitySlider.value / 100;
const blob = await processImage(item, mimeType, quality, false); // false = don't trigger download
return formatBytes(blob.size);
}
async function processAndDownload() {
if (filesToProcess.length === 0) {
alert("Please upload at least one image."); return;
}
const newNameTemplate = document.getElementById('img_fileNameInput').value.trim();
if (!newNameTemplate) {
alert("Please enter a new file name template."); return;
}
downloadBtn.disabled = true;
downloadBtn.innerHTML = '
Processing...';
let fileCounter = 1;
for (const item of filesToProcess) {
const newFormat = fileFormatSelect.value;
const mimeType = `image/${newFormat}`;
const quality = qualitySlider.value / 100;
const newName = newNameTemplate.replace('{n}', fileCounter++);
try {
const blob = await processImage(item, mimeType, quality, true); // true = trigger download
const a = document.createElement('a');
a.href = URL.createObjectURL(blob);
a.download = `${newName}.${newFormat}`;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(a.href);
} catch (error) {
console.error('Error processing file:', item.file.name, error);
alert(`Could not process file: ${item.file.name}`);
}
}
downloadBtn.disabled = false;
downloadBtn.innerHTML = '
Process & Download';
filesToProcess = [];
updateFileListUI();
}
function processImage(item, mimeType, quality) {
return new Promise((resolve, reject) => {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
const img = new Image();
img.crossOrigin = "Anonymous";
img.src = item.preview;
img.onload = () => {
const originalWidth = img.width;
const originalHeight = img.height;
let newWidth = widthInput.value ? parseInt(widthInput.value, 10) : originalWidth;
let newHeight = heightInput.value ? parseInt(heightInput.value, 10) : originalHeight;
const aspectRatio = originalWidth / originalHeight;
if (aspectRatioLock.checked) {
if (widthInput.value && !heightInput.value) {
newHeight = Math.round(newWidth / aspectRatio);
} else if (!widthInput.value && heightInput.value) {
newWidth = Math.round(newHeight * aspectRatio);
}
}
canvas.width = newWidth;
canvas.height = newHeight;
ctx.drawImage(img, 0, 0, newWidth, newHeight);
canvas.toBlob(blob => {
if (blob) resolve(blob);
else reject(new Error('Canvas toBlob failed.'));
}, mimeType, quality);
};
img.onerror = () => reject(new Error('Image could not be loaded.'));
});
}
// Initial UI update
updateFileListUI();
toggleQualitySlider();
});
Related Posts