You can edit the below JavaScript code to customize the image tool.
Apply Changes
async function processImage(originalImg, defaultFallback = "Minions") {
// We will analyze the dominant color hue of the uploaded image to "find" the matching
// Illumination Entertainment movie. Different movies have distinct color palettes.
// Calculate perceptual dominant hue
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
// Resize image for faster processing
const maxSize = 120;
let width = originalImg.width;
let height = originalImg.height;
if (width > height) {
height = Math.floor(height * (maxSize / width));
width = maxSize;
} else {
width = Math.floor(width * (maxSize / height));
height = maxSize;
}
canvas.width = width;
canvas.height = height;
ctx.drawImage(originalImg, 0, 0, width, height);
const imgData = ctx.getImageData(0, 0, width, height).data;
// Helper: RGB to HSV
const rgbToHsv = (r, g, b) => {
r /= 255; g /= 255; b /= 255;
let max = Math.max(r, g, b), min = Math.min(r, g, b);
let h, s, v = max;
let d = max - min;
s = max === 0 ? 0 : d / max;
if (max === min) {
h = 0; // achromatic
} else {
switch (max) {
case r: h = (g - b) / d + (g < b ? 6 : 0); break;
case g: h = (b - r) / d + 2; break;
case b: h = (r - g) / d + 4; break;
}
h /= 6;
}
return [h * 360, s, v];
};
let sumSin = 0;
let sumCos = 0;
let validPixels = 0;
for (let i = 0; i < imgData.length; i += 4) {
let r = imgData[i];
let g = imgData[i + 1];
let b = imgData[i + 2];
let [h, s, v] = rgbToHsv(r, g, b);
// Filter out extreme blacks, whites, and grays to find the true "colored" theme
if (s > 0.25 && v > 0.25) {
let rad = h * Math.PI / 180;
sumSin += Math.sin(rad);
sumCos += Math.cos(rad);
validPixels++;
}
}
let avgHue = 0;
if (validPixels > 0) {
let avgRad = Math.atan2(sumSin, sumCos);
avgHue = (avgRad * 180 / Math.PI + 360) % 360;
} else {
// Fallback for purely grayscale images: Deterministic pseudo-random based on image dims
avgHue = (originalImg.width * originalImg.height) % 360;
}
// Illumination Entertainment Movie Database mapped by typical Hue Palette
const illuminationDB = [
{
title: "The Super Mario Bros. Movie", year: 2023, director: "Aaron Horvath, Michael Jelenic",
hueRange: [345, 15], theme: "#E3001B",
synopsis: "With help from Princess Peach, Mario gets ready to square off against the all-powerful Bowser to stop his plans from conquering the world.",
characters: "Mario, Luigi, Princess Peach, Bowser"
},
{
title: "The Lorax", year: 2012, director: "Chris Renaud, Kyle Balda",
hueRange: [16, 39], theme: "#FF8C00",
synopsis: "A 12-year-old boy searches for the one thing that will enable him to win the affection of the girl of his dreams. To find it he must discover the story of the Lorax.",
characters: "The Lorax, Once-ler, Ted, Audrey"
},
{
title: "Minions", year: 2015, director: "Pierre Coffin, Kyle Balda",
hueRange: [40, 65], theme: "#F5E050",
synopsis: "Minions Stuart, Kevin, and Bob are recruited by Scarlet Overkill, a supervillain who, alongside her inventor husband Herb, hatches a plot to take over the world.",
characters: "Kevin, Stuart, Bob, Scarlet Overkill"
},
{
title: "The Grinch", year: 2018, director: "Scott Mosier, Yarrow Cheney",
hueRange: [66, 140], theme: "#70AC43",
synopsis: "A grumpy Grinch plots to ruin Christmas for the village of Whoville.",
characters: "The Grinch, Max, Cindy-Lou Who, Fred"
},
{
title: "Migration", year: 2023, director: "Benjamin Renner",
hueRange: [141, 179], theme: "#2E8B57",
synopsis: "A family of ducks try to convince their overprotective father to go on the vacation of a lifetime.",
characters: "Mack, Pam, Dax, Gwen"
},
{
title: "The Secret Life of Pets", year: 2016, director: "Chris Renaud",
hueRange: [180, 215], theme: "#00BFFF",
synopsis: "The quiet life of a terrier named Max is upended when his owner takes in Duke, a stray whom Max instantly dislikes.",
characters: "Max, Duke, Snowball, Gidget"
},
{
title: "Despicable Me", year: 2010, director: "Pierre Coffin, Chris Renaud",
hueRange: [216, 269], theme: "#4682B4",
synopsis: "When a criminal mastermind uses a trio of orphan girls as pawns for a grand scheme, he finds their love is profoundly changing him for the better.",
characters: "Gru, Vector, Margo, Edith, Agnes"
},
{
title: "Sing", year: 2016, director: "Garth Jennings",
hueRange: [270, 310], theme: "#8A2BE2",
synopsis: "In a city of humanoid animals, a hustling theater impresario's attempt to save his theater with a singing competition becomes grander than he anticipates.",
characters: "Buster Moon, Rosita, Johnny, Ash, Meena"
},
{
title: "Hop", year: 2011, director: "Tim Hill",
hueRange: [311, 344], theme: "#FF69B4",
synopsis: "E.B., the Easter Bunny's teenage son, heads to Hollywood, determined to become a drummer in a rock 'n' roll band.",
characters: "E.B., Fred O'Hare, Carlos, Phil"
}
];
let foundMovie = null;
for (let movie of illuminationDB) {
let [minH, maxH] = movie.hueRange;
if (minH > maxH) {
// Wraps around 360 (e.g. 345 to 15)
if (avgHue >= minH || avgHue <= maxH) { foundMovie = movie; break; }
} else {
if (avgHue >= minH && avgHue <= maxH) { foundMovie = movie; break; }
}
}
if (!foundMovie) {
// Safe fallback if calculation misses boundaries
foundMovie = illuminationDB.find(m => m.title === defaultFallback) || illuminationDB[2];
}
// Build the UI Container
const container = document.createElement('div');
const containerId = 'illumination-finder-' + Math.random().toString(36).substring(2, 9);
container.id = containerId;
// Inject Styles & Google Fonts
const styleEl = document.createElement('style');
styleEl.innerHTML = `
@import url('https://fonts.googleapis.com/css2?family=Nunito:wght@400;700;900&display=swap');
#${containerId} {
font-family: 'Nunito', sans-serif;
background: linear-gradient(145deg, #1f1c2c, #928DAB);
color: #ffffff;
padding: 30px;
border-radius: 16px;
box-shadow: 0 10px 30px rgba(0,0,0,0.5);
max-width: 500px;
margin: 0 auto;
position: relative;
overflow: hidden;
border: 2px solid rgba(255, 255, 255, 0.1);
}
#${containerId} .header {
text-align: center;
margin-bottom: 25px;
padding-bottom: 15px;
border-bottom: 1px dashed rgba(255, 255, 255, 0.3);
}
#${containerId} .header h2 {
margin: 0;
font-size: 24px;
font-weight: 900;
text-transform: uppercase;
letter-spacing: 1px;
color: #ffffff;
text-shadow: 2px 2px 4px rgba(0,0,0,0.3);
}
#${containerId} .header p {
margin: 5px 0 0 0;
font-size: 13px;
opacity: 0.8;
color: #ccc;
}
#${containerId} .card {
background: rgba(0, 0, 0, 0.4);
border-left: 8px solid ${foundMovie.theme};
padding: 20px;
border-radius: 8px;
backdrop-filter: blur(10px);
}
#${containerId} .movie-title {
margin: 0 0 10px 0;
font-size: 28px;
font-weight: 900;
color: ${foundMovie.theme};
text-shadow: 1px 1px 2px rgba(0,0,0,0.8);
}
#${containerId} .meta-info {
display: grid;
grid-template-columns: 100px 1fr;
gap: 5px;
font-size: 14px;
margin-bottom: 15px;
}
#${containerId} .meta-info strong {
color: #ccc;
}
#${containerId} .synopsis {
font-size: 15px;
line-height: 1.6;
margin: 0;
font-style: italic;
border-top: 1px solid rgba(255, 255, 255, 0.1);
padding-top: 15px;
}
#${containerId} .detected-pill {
display: inline-block;
background: ${foundMovie.theme};
color: ${(avgHue > 40 && avgHue < 180) ? '#000' : '#fff'};
padding: 4px 12px;
border-radius: 20px;
font-size: 11px;
font-weight: bold;
margin-bottom: 15px;
box-shadow: 0 2px 4px rgba(0,0,0,0.3);
}
#${containerId} .thumbnail-bg {
position: absolute;
top: -20%;
right: -20%;
width: 250px;
height: 250px;
opacity: 0.1;
border-radius: 50%;
pointer-events: none;
background: ${foundMovie.theme};
filter: blur(40px);
}
`;
container.appendChild(styleEl);
// Build the inner Content content
const content = document.createElement('div');
content.innerHTML = `
<div class="thumbnail-bg"></div>
<div class="header">
<h2>Illumination Matcher</h2>
<p>Analyzed image colors to find your cinematic match!</p>
</div>
<div class="card">
<span class="detected-pill">Dominant Hue: ${Math.round(avgHue)}°</span>
<h3 class="movie-title">${foundMovie.title} (${foundMovie.year})</h3>
<div class="meta-info">
<strong>Director:</strong> <span>${foundMovie.director}</span>
<strong>Characters:</strong> <span>${foundMovie.characters}</span>
</div>
<p class="synopsis">"${foundMovie.synopsis}"</p>
</div>
`;
container.appendChild(content);
return container;
}
Apply Changes