You can edit the below JavaScript code to customize the image tool.
Apply Changes
function processImage(originalImg, forceMovieMatch = "", theme = "dark") {
// 1. Setup Canvas and Dimensions
const canvas = document.createElement('canvas');
canvas.width = 900;
canvas.height = 500;
const ctx = canvas.getContext('2d');
// 2. Define Theme Colors
const isDark = theme.toLowerCase() !== "light";
const bgPrimary = isDark ? "#121212" : "#f0f2f5";
const bgSecondary = isDark ? "#1e1e24" : "#ffffff";
const textPrimary = isDark ? "#ffffff" : "#111111";
const textSecondary = isDark ? "#aaaaaa" : "#666666";
const accentColor = isDark ? "#00ffcc" : "#0055ff";
const uiBorder = isDark ? "#333333" : "#dddddd";
// 3. Illumination Entertainment Movie Database (Archetype base colors)
const movies = [
{ title: "Despicable Me (2010)", color: [160, 165, 170] },
{ title: "Hop (2011)", color: [240, 100, 180] },
{ title: "The Lorax (2012)", color: [253, 116, 0] },
{ title: "Minions (2015)", color: [245, 224, 76] },
{ title: "The Secret Life of Pets (2016)", color: [73, 172, 230] },
{ title: "Sing (2016)", color: [159, 90, 253] },
{ title: "The Grinch (2018)", color: [122, 193, 67] },
{ title: "The Super Mario Bros. Movie (2023)", color: [229, 37, 33] },
{ title: "Migration (2023)", color: [66, 203, 183] }
];
// 4. Analyze Origin Image for Dominant Features (Average RGB)
const tempCanvas = document.createElement('canvas');
tempCanvas.width = 64;
tempCanvas.height = 64;
const tCtx = tempCanvas.getContext('2d');
tCtx.drawImage(originalImg, 0, 0, 64, 64);
let rSum = 0, gSum = 0, bSum = 0;
let imgData;
try {
imgData = tCtx.getImageData(0, 0, 64, 64).data;
} catch(e) {
// Fallback for CORS issues (though usually safe if processed in allowed environments)
imgData = new Uint8ClampedArray(64 * 64 * 4).fill(128);
}
// Process pixels
let validPixels = 0;
for (let i = 0; i < imgData.length; i += 4) {
// skip fully transparent
if(imgData[i+3] > 0) {
rSum += imgData[i];
gSum += imgData[i+1];
bSum += imgData[i+2];
validPixels++;
}
}
if(validPixels === 0) validPixels = 1;
const avgR = Math.round(rSum / validPixels);
const avgG = Math.round(gSum / validPixels);
const avgB = Math.round(bSum / validPixels);
// 5. Calculate Closest Movie Match
let bestMatch = movies[0];
let minDistance = Infinity;
for (let m of movies) {
// Euclidean distance of RGB color space
let dist = Math.sqrt(
Math.pow(m.color[0] - avgR, 2) +
Math.pow(m.color[1] - avgG, 2) +
Math.pow(m.color[2] - avgB, 2)
);
if (dist < minDistance) {
minDistance = dist;
bestMatch = m;
}
}
// Allow overriding via parameter
if (forceMovieMatch && forceMovieMatch.trim().length > 0) {
bestMatch = {
title: forceMovieMatch,
color: [avgR, avgG, avgB]
};
minDistance = 25; // Fake a good match score
}
const maxDist = Math.sqrt(3 * Math.pow(255, 2));
const rawConfidence = Math.max(0, 100 - (minDistance / maxDist) * 100);
// Add a slight baseline so confidence always seems somewhat realistic for a mock search tool
const confidence = ((rawConfidence * 0.6) + 40).toFixed(1);
// 6. Draw UI Fundamentals
ctx.fillStyle = bgPrimary;
ctx.fillRect(0, 0, canvas.width, canvas.height);
// Top Header Bar
ctx.fillStyle = bgSecondary;
ctx.fillRect(0, 0, canvas.width, 50);
ctx.strokeStyle = uiBorder;
ctx.lineWidth = 1;
ctx.beginPath();
ctx.moveTo(0, 50);
ctx.lineTo(canvas.width, 50);
ctx.stroke();
ctx.fillStyle = textPrimary;
ctx.font = "bold 20px 'Trebuchet MS', Arial, sans-serif";
ctx.fillText("ıllumination Entertainment Content Search OS", 20, 32);
// 7. Left Panel - Image Analysis Render
ctx.fillStyle = bgSecondary;
ctx.fillRect(30, 80, 400, 390);
ctx.strokeRect(30, 80, 400, 390);
// Draw Original Image properly scaled
const boxW = 380;
const boxH = 350;
const boxX = 40;
const boxY = 110;
let scale = Math.min(boxW / originalImg.width, boxH / originalImg.height);
let drawW = originalImg.width * scale;
let drawH = originalImg.height * scale;
let drawX = boxX + (boxW - drawW) / 2;
let drawY = boxY + (boxH - drawH) / 2;
ctx.fillStyle = "#000000";
ctx.fillRect(boxX, boxY, boxW, boxH);
ctx.drawImage(originalImg, drawX, drawY, drawW, drawH);
// Draw "AI Analysis" targeting brackets over the image
ctx.strokeStyle = accentColor;
ctx.lineWidth = 2;
const bracketSize = 30;
// Top-Left
ctx.beginPath(); ctx.moveTo(drawX, drawY + bracketSize); ctx.lineTo(drawX, drawY); ctx.lineTo(drawX + bracketSize, drawY); ctx.stroke();
// Top-Right
ctx.beginPath(); ctx.moveTo(drawX + drawW - bracketSize, drawY); ctx.lineTo(drawX + drawW, drawY); ctx.lineTo(drawX + drawW, drawY + bracketSize); ctx.stroke();
// Bottom-Left
ctx.beginPath(); ctx.moveTo(drawX, drawY + drawH - bracketSize); ctx.lineTo(drawX, drawY + drawH); ctx.lineTo(drawX + bracketSize, drawY + drawH); ctx.stroke();
// Bottom-Right
ctx.beginPath(); ctx.moveTo(drawX + drawW, drawY + drawH - bracketSize); ctx.lineTo(drawX + drawW, drawY + drawH); ctx.lineTo(drawX + drawW - bracketSize, drawY + drawH); ctx.stroke();
// Image Label
ctx.fillStyle = textPrimary;
ctx.font = "bold 14px Arial";
ctx.fillText("SOURCE IMAGE TARGET", 40, 100);
// 8. Right Panel - Search Results
const rightX = 460;
ctx.fillStyle = bgSecondary;
ctx.fillRect(rightX, 80, 410, 390);
ctx.strokeRect(rightX, 80, 410, 390);
// Status Badge
const resultStatusColor = isDark ? "#00e676" : "#2e7d32";
ctx.fillStyle = resultStatusColor;
ctx.font = "bold 14px Arial";
ctx.fillText("â–º SEARCH COMPLETE", rightX + 20, 110);
ctx.fillStyle = textSecondary;
ctx.font = "16px Arial";
ctx.fillText("Closest Match Found in Catalog:", rightX + 20, 145);
// Movie Title (Bold & Colored)
let movieRGB = `rgb(${bestMatch.color[0]}, ${bestMatch.color[1]}, ${bestMatch.color[2]})`;
// Draw Title Background/Accent
ctx.fillStyle = movieRGB;
ctx.fillRect(rightX + 20, 160, 370, 60);
// Text contrasting
let lum = (0.299 * bestMatch.color[0] + 0.587 * bestMatch.color[1] + 0.114 * bestMatch.color[2]);
ctx.fillStyle = lum > 150 ? "#111111" : "#ffffff";
ctx.font = "bold 22px 'Trebuchet MS', Arial, sans-serif";
// Center Title theoretically, or left align
ctx.fillText(bestMatch.title, rightX + 35, 198);
// Match breakdown
ctx.fillStyle = textPrimary;
ctx.font = "bold 14px Arial";
ctx.fillText("MATCH DIAGNOSTICS", rightX + 20, 255);
// helper function to draw progress bars
function drawBar(yOffset, label, percentage, barColor) {
ctx.fillStyle = textSecondary;
ctx.font = "12px Arial";
ctx.fillText(label, rightX + 20, yOffset);
ctx.fillText(percentage + "%", rightX + 350, yOffset);
// Track
ctx.fillStyle = isDark ? "#333333" : "#e0e0e0";
ctx.fillRect(rightX + 20, yOffset + 10, 370, 8);
// Fill
ctx.fillStyle = barColor;
ctx.fillRect(rightX + 20, yOffset + 10, 370 * (percentage / 100), 8);
}
const featureConf = Math.min(100, (parseFloat(confidence) + (Math.random() * 15 - 5))).toFixed(1);
const colorConf = Math.min(100, (parseFloat(confidence) + (Math.random() * 20 - 5))).toFixed(1);
drawBar(280, "Color Profile Match", colorConf, movieRGB);
drawBar(320, "Subject / Feature Recognition", featureConf, accentColor);
drawBar(360, "Overall Match Confidence", confidence, resultStatusColor);
// Swatch box displaying detected dominant color vs matched color
ctx.fillStyle = textSecondary;
ctx.fillText("Detected Color vs Profile:", rightX + 20, 420);
ctx.fillStyle = `rgb(${avgR}, ${avgG}, ${avgB})`;
ctx.fillRect(rightX + 20, 430, 185, 20);
ctx.fillStyle = movieRGB;
ctx.fillRect(rightX + 205, 430, 185, 20);
return canvas;
}
Apply Changes