You can edit the below JavaScript code to customize the image tool.
Apply Changes
async function processImage(originalImg, includeAI = "yes") {
// Create the main container div
const container = document.createElement('div');
container.style.fontFamily = "'Segoe UI', Roboto, Helvetica, Arial, sans-serif";
container.style.border = "1px solid #e1e4e8";
container.style.borderRadius = "8px";
container.style.padding = "20px";
container.style.maxWidth = "650px";
container.style.backgroundColor = "#ffffff";
container.style.boxShadow = "0 4px 12px rgba(0,0,0,0.05)";
container.style.color = "#333";
container.style.boxSizing = "border-box";
// Title
const title = document.createElement('h2');
title.textContent = "Image ID Finder & Analysis";
title.style.marginTop = "0";
title.style.marginBottom = "20px";
title.style.fontSize = "22px";
title.style.borderBottom = "1px solid #eaedf1";
title.style.paddingBottom = "10px";
title.style.color = "#24292e";
container.appendChild(title);
// Layout: image left, data right
const splitView = document.createElement('div');
splitView.style.display = "flex";
splitView.style.gap = "25px";
splitView.style.flexWrap = "wrap";
splitView.style.alignItems = "flex-start";
// Image preview
const imgPreview = document.createElement('img');
imgPreview.src = originalImg.src;
imgPreview.style.maxWidth = "220px";
imgPreview.style.maxHeight = "220px";
imgPreview.style.width = "100%";
imgPreview.style.objectFit = "scale-down";
imgPreview.style.borderRadius = "6px";
imgPreview.style.border = "1px solid #d1d5da";
imgPreview.style.backgroundColor = "#f9f9f9";
splitView.appendChild(imgPreview);
// Details Container
const detailsContainer = document.createElement('div');
detailsContainer.style.flex = "1";
detailsContainer.style.minWidth = "260px";
splitView.appendChild(detailsContainer);
container.appendChild(splitView);
// Helper to add property lines
const addInfoLine = (label, value, id = "") => {
const p = document.createElement('p');
p.style.margin = "10px 0";
p.style.fontSize = "14px";
p.style.lineHeight = "1.4";
p.innerHTML = `<strong style="color: #0366d6; display: block; margin-bottom: 3px;">${label}</strong> `;
const valSpan = document.createElement('span');
if (id) valSpan.id = id;
valSpan.innerHTML = value;
p.appendChild(valSpan);
detailsContainer.appendChild(p);
return p;
};
// Synchronous Computations
// 1. Dimensions
addInfoLine("Dimensions", `${originalImg.width} x ${originalImg.height} pixels`);
// 2. Perceptual dHash (Visual ID)
const dHash = calculateDHash(originalImg);
addInfoLine("Visual ID (Perceptual Hash)", `<code style="background:#f6f8fa;padding:3px 6px;border-radius:4px;font-family:monospace;letter-spacing:1px;">${dHash}</code>`);
// 3. Dominant Color ID
const colorId = calculateAverageColor(originalImg);
addInfoLine("Dominant Color Hex ID", `
<div style="display:flex; align-items:center;">
<span style="display:inline-block;width:16px;height:16px;background:${colorId};border:1px solid #d1d5da;border-radius:3px;margin-right:8px;"></span>
<code style="background:#f6f8fa;padding:3px 6px;border-radius:4px;font-family:monospace;">${colorId}</code>
</div>
`);
// Asynchronous Computations Placeholders
// 4. Barcode/QR Code ID placeholder
const barcodeIdEl = addInfoLine("Scanned Barcodes/QR Codes", "<span style='color:#666;'><i>Scanning...</i></span>", "barcode-id-span");
// 5. File Pixel Hash ID Placeholder
const exactIdEl = addInfoLine("Pixel Hash ID (SHA-256)", "<span style='color:#666;'><i>Calculating...</i></span>", "exact-id-span");
// 6. AI Content Identity Placeholder
let aiIdEl = null;
if (includeAI.toLowerCase() === "yes" || includeAI === "1" || includeAI === "true") {
aiIdEl = addInfoLine("Content Identification (AI)", "<span style='color:#666;'><i>Loading AI model...</i></span>", "ai-id-span");
}
// Fire asynchronous background operations
setTimeout(async () => {
try {
// Attempt Barcode Detection (if supported natively by browser)
try {
if ('BarcodeDetector' in window) {
const barcodeDetector = new BarcodeDetector();
const barcodes = await barcodeDetector.detect(originalImg);
const barcodeSpan = detailsContainer.querySelector("#barcode-id-span");
if (barcodes.length > 0) {
const bText = barcodes.map(b => b.rawValue).join(' | ');
if (barcodeSpan) barcodeSpan.innerHTML = `<strong>Found:</strong> <code style="background:#f6f8fa;padding:2px 4px;border-radius:4px;">${bText}</code>`;
} else {
if (barcodeSpan) barcodeSpan.innerHTML = "None found in image";
}
} else {
const barcodeSpan = detailsContainer.querySelector("#barcode-id-span");
if (barcodeSpan) barcodeSpan.innerHTML = "<em>Not supported by current browser</em>";
}
} catch (e) {
const barcodeSpan = detailsContainer.querySelector("#barcode-id-span");
if (barcodeSpan) barcodeSpan.innerHTML = "<em>Error scanning barcodes</em>";
}
// Create Canvas to extract reliable pixel data
const canvas = document.createElement('canvas');
canvas.width = originalImg.width;
canvas.height = originalImg.height;
const ctx = canvas.getContext('2d');
ctx.drawImage(originalImg, 0, 0);
// Generate SHA-256 Pixel Hash ID
canvas.toBlob(async (blob) => {
try {
const buffer = await blob.arrayBuffer();
const hashBuffer = await crypto.subtle.digest('SHA-256', buffer);
const hashArray = Array.from(new Uint8Array(hashBuffer));
const hashHex = hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
const exactSpan = detailsContainer.querySelector("#exact-id-span");
if (exactSpan) {
exactSpan.innerHTML = `<code style="background:#f6f8fa;padding:3px 6px;border-radius:4px;word-break:break-all;font-family:monospace;display:block;">${hashHex}</code>`;
}
} catch(e) {
const exactSpan = detailsContainer.querySelector("#exact-id-span");
if (exactSpan) exactSpan.innerHTML = "<em>Unavailable</em>";
}
}, 'image/png');
// Content Identity Identification via TensorFlow.js MobileNet
if (aiIdEl) {
try {
// Helper to dynamically load external scripts without duplication
const loadJs = (url, checkObj) => {
if (window[checkObj]) return Promise.resolve(window[checkObj]);
return new Promise((resolve, reject) => {
const script = document.createElement('script');
script.src = url;
script.crossOrigin = "anonymous";
script.onload = () => resolve(window[checkObj]);
script.onerror = reject;
document.head.appendChild(script);
});
};
await loadJs('https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@3.21.0/dist/tf.min.js', 'tf');
await loadJs('https://cdn.jsdelivr.net/npm/@tensorflow-models/mobilenet@2.1.0/dist/mobilenet.min.js', 'mobilenet');
const aiSpan = detailsContainer.querySelector("#ai-id-span");
if (aiSpan) aiSpan.innerHTML = "<span style='color:#666;'><i>Analyzing image content...</i></span>";
const model = await window.mobilenet.load();
const predictions = await model.classify(originalImg);
if (predictions && predictions.length > 0) {
let aiHtml = `<ul style="margin:8px 0; padding-left:22px; list-style-type:circle;">`;
predictions.forEach(p => {
let percent = (p.probability * 100).toFixed(1) + "%";
aiHtml += `<li style="margin-bottom:4px;">Identifies as <strong>${p.className.split(',')[0]}</strong> <span style="color:#586069;font-size:12px;">(${percent} confidence)</span></li>`;
});
aiHtml += `</ul>`;
if (aiSpan) aiSpan.innerHTML = aiHtml;
} else {
if (aiSpan) aiSpan.innerHTML = "<em>No specific identities found.</em>";
}
} catch(e) {
const aiSpan = detailsContainer.querySelector("#ai-id-span");
if (aiSpan) aiSpan.innerHTML = `<em>Failed to identify (Cross-Origin restricted or connection issue)</em>`;
}
}
} catch (e) {
console.error("Image Processing Error:", e);
}
}, 50);
return container;
// --- Helper Functions ---
/**
* Calculates the Difference Hash (dHash) to produce a perceptual visual ID
*/
function calculateDHash(img) {
const hCanvas = document.createElement('canvas');
hCanvas.width = 9;
hCanvas.height = 8;
const hCtx = hCanvas.getContext('2d');
hCtx.drawImage(img, 0, 0, 9, 8);
try {
const data = hCtx.getImageData(0, 0, 9, 8).data;
const grays = [];
// Convert to Grayscale
for (let i = 0; i < data.length; i += 4) {
grays.push(data[i] * 0.299 + data[i+1] * 0.587 + data[i+2] * 0.114);
}
// Compute Hash gradients
let hash = '';
for (let y = 0; y < 8; y++) {
for (let x = 0; x < 8; x++) {
const left = grays[y * 9 + x];
const right = grays[y * 9 + x + 1];
hash += (left > right ? '1' : '0');
}
}
// Binary string to Hex string ID
let hex = '';
for (let i = 0; i < 64; i += 4) {
hex += parseInt(hash.substr(i, 4), 2).toString(16);
}
return hex;
} catch (e) {
return "Cross-Origin Restricted";
}
}
/**
* Calculates a simple Average Color representation as Hex string
*/
function calculateAverageColor(img) {
const sCanvas = document.createElement('canvas');
sCanvas.width = 100;
sCanvas.height = 100; // Sample across a 100x100 grid for speed
const sCtx = sCanvas.getContext('2d');
sCtx.drawImage(img, 0, 0, 100, 100);
try {
const data = sCtx.getImageData(0, 0, 100, 100).data;
let r=0, g=0, b=0;
const totalPixels = data.length / 4;
for (let i=0; i < data.length; i+=4) {
r += data[i];
g += data[i+1];
b += data[i+2];
}
r = Math.round(r / totalPixels);
g = Math.round(g / totalPixels);
b = Math.round(b / totalPixels);
// Convert averaged RGB to Hex ID
return "#" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1).toUpperCase();
} catch (e) {
return "#000000";
}
}
}
Apply Changes