You can edit the below JavaScript code to customize the image tool.
Apply Changes
function processImage(originalImg, themeColor = "#00ff00", scanSpeed = 3) {
const themeColorValue = typeof themeColor === 'string' ? themeColor : "#00ff00";
const speedValue = typeof scanSpeed === 'number' ? scanSpeed : 3;
// Parse theme color to RGB for edge detection manipulation
let r = 0, g = 255, b = 0;
if (themeColorValue.startsWith('#') && themeColorValue.length === 7) {
r = parseInt(themeColorValue.slice(1, 3), 16);
g = parseInt(themeColorValue.slice(3, 5), 16);
b = parseInt(themeColorValue.slice(5, 7), 16);
}
const container = document.createElement('div');
container.style.position = 'relative';
container.style.display = 'inline-block';
container.style.overflow = 'hidden';
container.style.fontFamily = "'Courier New', Courier, monospace";
// Scale down image if it's too large to maintain performance
let width = originalImg.width;
let height = originalImg.height;
const MAX_DIM = 800;
if (width > MAX_DIM || height > MAX_DIM) {
const ratio = Math.min(MAX_DIM / width, MAX_DIM / height);
width = Math.round(width * ratio);
height = Math.round(height * ratio);
}
// Base Canvas
const canvas = document.createElement('canvas');
canvas.width = width;
canvas.height = height;
const ctx = canvas.getContext('2d');
// Fill back to prevent transparency issues
ctx.fillStyle = '#111111';
ctx.fillRect(0, 0, width, height);
ctx.drawImage(originalImg, 0, 0, width, height);
container.appendChild(canvas);
// Unique ID for scoped CSS
const UID = Math.random().toString(36).substring(2, 9);
const style = document.createElement('style');
style.innerHTML = `
@keyframes scanline-${UID} {
0% { top: 0%; }
50% { top: 100%; }
100% { top: 0%; }
}
@keyframes pulse-${UID} {
0% { opacity: 0.1; }
50% { opacity: 0.7; }
100% { opacity: 0.1; }
}
.hud-${UID} {
position: absolute;
top: 40px;
left: 40px;
background: rgba(0, 10, 0, 0.75);
color: ${themeColorValue};
border: 1px solid ${themeColorValue};
padding: 12px;
font-size: 14px;
z-index: 10;
border-radius: 4px;
text-shadow: 0 0 5px ${themeColorValue};
box-shadow: 0 0 10px rgba(0, 0, 0, 0.5), inset 0 0 10px rgba(0, 0, 0, 0.8);
pointer-events: none;
max-width: calc(100% - 80px);
word-wrap: break-word;
line-height: 1.4;
}
.scanner-${UID} {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 2px;
background: ${themeColorValue};
box-shadow: 0 0 15px 3px ${themeColorValue};
animation: scanline-${UID} ${speedValue}s linear infinite;
z-index: 5;
pointer-events: none;
}
.marker-${UID} {
position: absolute;
width: 30px;
height: 30px;
border: 3px solid ${themeColorValue};
box-shadow: 0 0 5px ${themeColorValue}, inset 0 0 5px ${themeColorValue};
z-index: 6;
pointer-events: none;
}
.tl-${UID} { top: 10px; left: 10px; border-right: none; border-bottom: none; }
.tr-${UID} { top: 10px; right: 10px; border-left: none; border-bottom: none; }
.bl-${UID} { bottom: 10px; left: 10px; border-right: none; border-top: none; }
.br-${UID} { bottom: 10px; right: 10px; border-left: none; border-top: none; }
`;
container.appendChild(style);
// Frame markers
['tl', 'tr', 'bl', 'br'].forEach(pos => {
const m = document.createElement('div');
m.className = `marker-${UID} ${pos}-${UID}`;
container.appendChild(m);
});
const scanner = document.createElement('div');
scanner.className = `scanner-${UID}`;
container.appendChild(scanner);
const hud = document.createElement('div');
hud.className = `hud-${UID}`;
hud.innerHTML = `[ SYSTEM START ]<br/>Booting Building Scanner...`;
container.appendChild(hud);
// Process scanning and neural network classification asynchronously to avoid blocking UI immediately
setTimeout(() => {
hud.innerHTML = `[ STEP 1 ]<br/>Analyzing Structural Topography...`;
let edgeCanvas;
setTimeout(() => {
try {
// Structural Edge Detection Simulation
const imageData = ctx.getImageData(0, 0, width, height);
const data = imageData.data;
const gray = new Float32Array(width * height);
// Convert to grayscale
for (let i = 0; i < data.length; i += 4) {
gray[i / 4] = 0.299 * data[i] + 0.587 * data[i+1] + 0.114 * data[i+2];
}
const edgeData = new Uint8ClampedArray(data.length);
for (let y = 1; y < height - 1; y++) {
for (let x = 1; x < width - 1; x++) {
let pixelX = 0;
let pixelY = 0;
const offset0 = (y - 1) * width + x;
const offset1 = y * width + x;
const offset2 = (y + 1) * width + x;
// Sobel Kernel applying
pixelX += gray[offset0 - 1] * -1 + gray[offset0 + 1] * 1;
pixelX += gray[offset1 - 1] * -2 + gray[offset1 + 1] * 2;
pixelX += gray[offset2 - 1] * -1 + gray[offset2 + 1] * 1;
pixelY += gray[offset0 - 1] * -1 + gray[offset0] * -2 + gray[offset0 + 1] * -1;
pixelY += gray[offset2 - 1] * 1 + gray[offset2] * 2 + gray[offset2 + 1] * 1;
const magnitude = Math.sqrt(pixelX * pixelX + pixelY * pixelY);
const idx = offset1 * 4;
edgeData[idx] = r;
edgeData[idx+1] = g;
edgeData[idx+2] = b;
edgeData[idx+3] = magnitude > 60 ? 180 : 0; // Alpha
}
}
const newImgData = new ImageData(edgeData, width, height);
edgeCanvas = document.createElement('canvas');
edgeCanvas.width = width;
edgeCanvas.height = height;
edgeCanvas.style.position = 'absolute';
edgeCanvas.style.top = '0';
edgeCanvas.style.left = '0';
edgeCanvas.style.animation = `pulse-${UID} 1.5s infinite`;
edgeCanvas.style.pointerEvents = 'none';
edgeCanvas.style.zIndex = '2';
edgeCanvas.getContext('2d').putImageData(newImgData, 0, 0);
container.appendChild(edgeCanvas);
} catch (err) {
console.warn("Edge detection skipped (likely CORS restrictions):", err);
}
hud.innerHTML = `[ STEP 2 ]<br/>Connecting to Inference Network...`;
const tfScriptUrl = 'https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@3.21.0/dist/tf.min.js';
const mnScriptUrl = 'https://cdn.jsdelivr.net/npm/@tensorflow-models/mobilenet@2.1.0/dist/mobilenet.min.js';
const loadScript = (src) => {
return new Promise((resolve, reject) => {
if (document.querySelector(`script[src="${src}"]`)) return resolve();
const s = document.createElement('script');
s.src = src;
s.onload = resolve;
s.onerror = reject;
document.head.appendChild(s);
});
};
const identifyImage = async () => {
try {
if (!window.tf) await loadScript(tfScriptUrl);
if (!window.mobilenet) await loadScript(mnScriptUrl);
hud.innerHTML = `[ STEP 3 ]<br/>Neural Nets Online.<br/>Running Architectural Classifier...`;
const model = await window.mobilenet.load({ version: 2, alpha: 1.0 });
const predictions = await model.classify(canvas);
scanner.style.display = 'none';
if (edgeCanvas) {
edgeCanvas.style.animation = 'none';
edgeCanvas.style.opacity = '0.35'; // Keep UI aesthetic active
}
const topMatch = predictions[0];
const labels = topMatch.className.toLowerCase();
const buildingKeywords = [
'palace', 'castle', 'monastery', 'church', 'mosque', 'stupa', 'planetarium',
'restaurant', 'cinema', 'theater', 'theatre', 'boathouse', 'greenhouse',
'library', 'barn', 'lighthouse', 'beacon', 'dam', 'bridge', 'viaduct',
'arch', 'dome', 'vault', 'prison', 'shop', 'store', 'house', 'building',
'obelisk', 'tower', 'skyscaper', 'pyramid', 'shrine', 'piazza', 'stadium',
'hotel', 'home', 'pier', 'villa', 'office', 'school', 'hospital', 'factory',
'lumbermill', 'sawmill', 'pharos', 'breakwater', 'groin', 'groyne', 'mole',
'bulwark', 'seawall', 'jetty'
];
const isBuilding = buildingKeywords.some(kw => labels.includes(kw));
const confidence = (topMatch.probability * 100).toFixed(2);
hud.innerHTML = `
<div style="font-weight:bold; font-size:16px; border-bottom:1px solid ${themeColorValue}; margin-bottom:8px; padding-bottom:5px;">
SCAN COMPLETE
</div>
<div style="margin-bottom: 4px;"><b>Match:</b> ${topMatch.className.toUpperCase()}</div>
<div style="margin-bottom: 4px;"><b>Confidence:</b> ${confidence}%</div>
<div style="margin-bottom: 10px;"><b>Category:</b> <span style="${isBuilding ? 'color: #fff; background: ' + themeColorValue + '; padding: 0 4px; color: #000;' : ''}">${isBuilding ? 'ARCHITECTURAL STRUCTURE' : 'NON-BUILDING OBJECT'}</span></div>
<div style="font-size:12px; margin-top: 10px;">Alternative Signatures:</div>
<ul style="margin:5px 0 0 20px; padding:0; font-size:12px;">
<li>${predictions[1].className} (${(predictions[1].probability*100).toFixed(1)}%)</li>
<li>${predictions[2].className} (${(predictions[2].probability*100).toFixed(1)}%)</li>
</ul>
`;
} catch (e) {
hud.innerHTML = `[ ERROR ]<br/>Identification failed: ${e.message}`;
scanner.style.display = 'none';
if (edgeCanvas) edgeCanvas.style.animation = 'none';
}
};
identifyImage();
}, 150);
}, 600);
return container;
}
Apply Changes