You can edit the below JavaScript code to customize the image tool.
Apply Changes
async function processImage(originalImg) {
// Helper function to format bytes into a human-readable string
function formatBytes(bytes, decimals = 2) {
if (typeof bytes !== 'number' || isNaN(bytes) || !isFinite(bytes) || bytes === 0) {
// Handles non-numeric inputs, NaN, Infinity, or 0 bytes
if (typeof bytes === 'string') return bytes; // Return error strings as is
return '0 Bytes';
}
const k = 1024;
const dm = decimals < 0 ? 0 : decimals;
const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
}
// Helper function to get file size and type from a URL
async function getFileSizeAndType(url) {
if (!url || typeof url !== 'string') {
return { size: 'N/A (No source URL)', type: 'N/A' };
}
if (url.startsWith('data:')) {
const mimeType = url.substring(url.indexOf(':') + 1, url.indexOf(';'));
const base64String = url.substring(url.indexOf(',') + 1);
const stringLength = base64String.length;
// Adjust for padding characters
let padding = 0;
if (base64String.endsWith('==')) {
padding = 2;
} else if (base64String.endsWith('=')) {
padding = 1;
}
const sizeInBytes = (stringLength * 3 / 4) - padding;
return { size: sizeInBytes, type: mimeType || 'N/A' };
} else if (url.startsWith('blob:')) {
try {
const response = await fetch(url);
if (!response.ok) {
return { size: `N/A (Fetch failed: ${response.status})`, type: 'N/A' };
}
const blob = await response.blob();
return { size: blob.size, type: blob.type || 'N/A' };
} catch (error) {
console.error('Error fetching blob URL:', error);
return { size: 'N/A (Fetch error)', type: 'N/A' };
}
} else { // Assumed http/https URL or relative path
try {
// Try HEAD request first
const headResponse = await fetch(url, { method: 'HEAD' });
if (headResponse.ok) {
const sizeHeader = headResponse.headers.get('content-length');
const typeHeader = headResponse.headers.get('content-type');
if (sizeHeader) {
return { size: parseInt(sizeHeader, 10), type: typeHeader || 'N/A' };
}
// If no content-length, fall through to GET, but use type if available
}
// Fallback to GET request
const getResponse = await fetch(url);
if (!getResponse.ok) {
return { size: `N/A (Fetch failed: ${getResponse.status})`, type: 'N/A' };
}
const blob = await getResponse.blob();
// Use blob.type if available, otherwise Content-Type header from GET response
const type = blob.type || getResponse.headers.get('content-type') || 'N/A';
return { size: blob.size, type: type };
} catch (error) {
console.error('Error fetching image size/type:', error);
if (url.startsWith('http:') || url.startsWith('https:')) {
// Common issue for external URLs
return { size: 'N/A (Fetch error, possibly CORS)', type: 'N/A' };
}
return { size: 'N/A (Fetch error)', type: 'N/A' };
}
}
}
const resultDiv = document.createElement('div');
resultDiv.style.fontFamily = 'Arial, sans-serif';
resultDiv.style.padding = '15px';
resultDiv.style.border = '1px solid #ddd';
resultDiv.style.borderRadius = '8px';
resultDiv.style.backgroundColor = '#f9f9f9';
resultDiv.style.maxWidth = '400px'; // Max width for better layout
const title = document.createElement('h3');
title.textContent = 'Image Analysis Report';
title.style.marginTop = '0';
title.style.marginBottom = '15px';
title.style.fontSize = '18px';
title.style.color = '#333';
title.style.borderBottom = '1px solid #eee';
title.style.paddingBottom = '10px';
resultDiv.appendChild(title);
function addInfoPair(label, value) {
const p = document.createElement('p');
p.style.margin = '8px 0';
p.style.fontSize = '14px';
p.style.color = '#555';
const strong = document.createElement('strong');
strong.textContent = label + ': ';
strong.style.color = '#333';
p.appendChild(strong);
p.appendChild(document.createTextNode(value));
resultDiv.appendChild(p);
return p; // Return the paragraph element for potential updates
}
addInfoPair('Width', `${originalImg.naturalWidth} pixels`);
addInfoPair('Height', `${originalImg.naturalHeight} pixels`);
const typeP = addInfoPair('Image Type', 'Fetching...');
const sizeP = addInfoPair('Approx. File Size', 'Calculating...');
// Asynchronously fetch and update file size and type
// Use currentSrc if available and src is relative, otherwise src.
// For simplicity and standard behavior, stick with `originalImg.src`.
// Browsers automatically resolve relative `src` to absolute URLs for fetch.
getFileSizeAndType(originalImg.src).then(info => {
const fileSizeDisplay = formatBytes(info.size);
sizeP.childNodes[1].nodeValue = fileSizeDisplay; // Update text node
typeP.childNodes[1].nodeValue = info.type || 'N/A'; // Update text node
}).catch(error => {
console.error("Error in getFileSizeAndType promise:", error);
sizeP.childNodes[1].nodeValue = 'Error';
typeP.childNodes[1].nodeValue = 'Error';
});
return resultDiv;
}
Apply Changes