You can edit the below JavaScript code to customize the image tool.
Apply Changes
function processImage(originalImg, confidenceThreshold = "0.4", scannerColor = "#00ff00") {
// Determine the threshold as a float from string
const threshold = parseFloat(confidenceThreshold) || 0.4;
// Create the outer wrapper element
const container = document.createElement('div');
container.style.position = 'relative';
container.style.display = 'inline-block';
container.style.overflow = 'hidden';
container.style.maxWidth = '100%';
container.style.borderRadius = '8px';
container.style.boxShadow = '0 4px 12px rgba(0,0,0,0.3)';
// Set up the main primary canvas
const canvas = document.createElement('canvas');
canvas.width = originalImg.width;
canvas.height = originalImg.height;
canvas.style.maxWidth = '100%';
canvas.style.height = 'auto';
canvas.style.display = 'block';
const ctx = canvas.getContext('2d');
ctx.drawImage(originalImg, 0, 0);
container.appendChild(canvas);
// Provide a unique animation name for the CSS scanner effect to avoid global collisions
const animName = 'mediateka-scan-' + Math.random().toString(36).substring(2, 9);
const style = document.createElement('style');
style.innerHTML = `
@keyframes ${animName} {
0% { top: 0%; opacity: 0; }
10% { opacity: 1; }
90% { opacity: 1; }
100% { top: 100%; opacity: 0; }
}
`;
document.head.appendChild(style);
// Create a visual scanning laser line overlay
const scannerLine = document.createElement('div');
scannerLine.style.position = 'absolute';
scannerLine.style.left = '0';
scannerLine.style.width = '100%';
scannerLine.style.height = '3px';
scannerLine.style.backgroundColor = scannerColor;
scannerLine.style.boxShadow = `0 0 12px ${scannerColor}, 0 0 24px ${scannerColor}`;
scannerLine.style.animation = `${animName} 2s linear infinite`;
scannerLine.style.zIndex = '10';
container.appendChild(scannerLine);
// Status / HUD message box to indicate progress
const statusBox = document.createElement('div');
statusBox.style.position = 'absolute';
statusBox.style.top = '10px';
statusBox.style.left = '10px';
statusBox.style.backgroundColor = 'rgba(0, 0, 0, 0.7)';
statusBox.style.color = '#fff';
statusBox.style.padding = '8px 12px';
statusBox.style.borderRadius = '4px';
statusBox.style.fontFamily = 'monospace';
statusBox.style.fontSize = '14px';
statusBox.style.zIndex = '20';
statusBox.innerText = 'INITIALIZING MEDIATEKA SCANNER...';
container.appendChild(statusBox);
// Helper logic to dynamically load external scripts without duplication
const loadScript = (src, checkGlobal) => new Promise((resolve, reject) => {
if (window[checkGlobal]) return resolve(); // Already in memory
// Wait if the script tag was already injected elsewhere but is loading
const existing = document.querySelector(`script[src="${src}"]`);
if (existing) {
const interval = setInterval(() => {
if (window[checkGlobal]) {
clearInterval(interval);
resolve();
}
}, 100);
return;
}
// Creating and injecting a new script tag
const s = document.createElement('script');
s.src = src;
s.onload = () => resolve();
s.onerror = () => reject(new Error('Failed to load: ' + src));
document.head.appendChild(s);
});
// Helper function to figure out a readable text color against a background color
const computeContrastColor = (colorStr) => {
const tempCtx = document.createElement('canvas').getContext('2d');
tempCtx.fillStyle = colorStr;
const hex = tempCtx.fillStyle;
if(hex.startsWith('#')) {
const r = parseInt(hex.substring(1,3), 16);
const g = parseInt(hex.substring(3,5), 16);
const b = parseInt(hex.substring(5,7), 16);
const yiq = ((r*299) + (g*587) + (b*114)) / 1000;
return (yiq >= 128) ? '#000000' : '#FFFFFF';
}
return '#000000';
};
// Run the Machine Learning scanning process asynchronously while returning the container immediately
(async () => {
try {
statusBox.innerText = '[1/3] LOADING TENSORFLOW ENGINE...';
await loadScript('https://cdn.jsdelivr.net/npm/@tensorflow/tfjs', 'tf');
statusBox.innerText = '[2/3] LOADING DETECTION MODEL...';
await loadScript('https://cdn.jsdelivr.net/npm/@tensorflow-models/coco-ssd', 'cocoSsd');
statusBox.innerText = '[3/3] ANALYZING AND IDENTIFYING...';
const model = await window.cocoSsd.load();
// Run object detection model
const predictions = await model.detect(originalImg);
// Clean up scanner visual overlays upon processing completion
scannerLine.remove();
statusBox.remove();
style.remove();
// Re-render image base to verify clean state
ctx.drawImage(originalImg, 0, 0);
// Keep track of counts for summary
let objectsIdentified = 0;
// Draw bounding boxes, identification names, and probability indices
predictions.forEach(prediction => {
if (prediction.score >= threshold) {
objectsIdentified++;
const [x, y, width, height] = prediction.bbox;
const scorePercent = Math.round(prediction.score * 100) + '%';
const labelText = `${prediction.class.toUpperCase()} ${scorePercent}`;
// Bounding Box Reticule
ctx.strokeStyle = scannerColor;
ctx.lineWidth = Math.max(2, Math.floor(originalImg.width / 250));
ctx.strokeRect(x, y, width, height);
// Configure Label Font & Dimensions
const fontSize = Math.max(12, Math.floor(originalImg.width / 50));
ctx.font = `bold ${fontSize}px Courier New, monospace`;
const textWidth = ctx.measureText(labelText).width;
const textHeight = fontSize + 4;
// Label Background Box
ctx.fillStyle = scannerColor;
ctx.globalAlpha = 0.85;
ctx.fillRect(x, Math.max(0, y - textHeight - 4), textWidth + 8, textHeight + 4);
// Label Text Foreground
ctx.fillStyle = computeContrastColor(scannerColor);
ctx.globalAlpha = 1.0;
ctx.fillText(labelText, x + 4, Math.max(textHeight, y - 6));
}
});
// If nothing met the threshold requirements
if (objectsIdentified === 0) {
const noTarget = document.createElement('div');
noTarget.style.position = 'absolute';
noTarget.style.bottom = '10px';
noTarget.style.left = '50%';
noTarget.style.transform = 'translateX(-50%)';
noTarget.style.backgroundColor = 'rgba(255, 60, 60, 0.9)';
noTarget.style.color = '#fff';
noTarget.style.padding = '8px 16px';
noTarget.style.borderRadius = '4px';
noTarget.style.fontFamily = 'monospace';
noTarget.style.fontSize = '14px';
noTarget.style.zIndex = '20';
noTarget.innerText = 'NO IDENTIFIABLE TARGETS FOUND.';
container.appendChild(noTarget);
}
} catch (err) {
statusBox.innerText = 'ERROR: MEDIATEKA SCANNER FAILURE';
statusBox.style.backgroundColor = 'rgba(200, 0, 0, 0.9)';
scannerLine.style.animationPlayState = 'paused';
console.error('Detection framework error:', err);
}
})();
// Returns an auto-updating interactive node sequence matching visual HUD demands
return container;
}
Apply Changes