You can edit the below JavaScript code to customize the image tool.
Apply Changes
async function processImage(originalImg, title = "THE CONJURING", subtitle = "THE DEVIL MADE ME DO IT") {
const canvas = document.createElement('canvas');
const w = originalImg.width;
const h = originalImg.height;
canvas.width = w;
canvas.height = h;
const ctx = canvas.getContext('2d');
// Draw the original image onto the canvas
ctx.drawImage(originalImg, 0, 0, w, h);
// Apply intense, moody color grading typical of "The Conjuring" franchise
const imgData = ctx.getImageData(0, 0, w, h);
const data = imgData.data;
const contrast = 1.6;
const shadowTeal = { r: 5, g: 20, b: 35 }; // Extremely dark cyan/blue shadows
const highlightWarm = { r: 180, g: 210, b: 230 }; // Pale, cold moonlight highlights
for (let i = 0; i < data.length; i += 4) {
const r = data[i];
const g = data[i + 1];
const b = data[i + 2];
// Calculate perceptual luminance
const luma = 0.299 * r + 0.587 * g + 0.114 * b;
// Apply contrast curve to luminance
let adjustedLuma = ((luma / 255 - 0.5) * contrast + 0.5) * 255;
adjustedLuma = Math.max(0, Math.min(255, adjustedLuma));
// Create duotone gradient map based on luminance
const blend = adjustedLuma / 255;
const tr = shadowTeal.r * (1 - blend) + highlightWarm.r * blend;
const tg = shadowTeal.g * (1 - blend) + highlightWarm.g * blend;
const tb = shadowTeal.b * (1 - blend) + highlightWarm.b * blend;
// Apply contrast to original channels to preserve some texture
const cr = Math.max(0, Math.min(255, ((r / 255 - 0.5) * contrast + 0.5) * 255));
const cg = Math.max(0, Math.min(255, ((g / 255 - 0.5) * contrast + 0.5) * 255));
const cb = Math.max(0, Math.min(255, ((b / 255 - 0.5) * contrast + 0.5) * 255));
// Blend gradient map (85%) with original high-contrast color (15%)
let finalR = tr * 0.85 + cr * 0.15;
let finalG = tg * 0.85 + cg * 0.15;
let finalB = tb * 0.85 + cb * 0.15;
// Add cinematic film grain (Noise)
const noise = (Math.random() - 0.5) * 20;
data[i] = Math.max(0, Math.min(255, finalR + noise));
data[i + 1] = Math.max(0, Math.min(255, finalG + noise));
data[i + 2] = Math.max(0, Math.min(255, finalB + noise));
}
ctx.putImageData(imgData, 0, 0);
// Apply eerie mist/fog gradient from the bottom
const fogGrad = ctx.createLinearGradient(0, h * 0.4, 0, h);
fogGrad.addColorStop(0, 'rgba(100, 130, 150, 0)');
fogGrad.addColorStop(1, 'rgba(80, 110, 130, 0.4)');
ctx.fillStyle = fogGrad;
ctx.fillRect(0, 0, w, h);
// Apply deep radial vignette to darken the edges (focusing on center)
const vignetteGrad = ctx.createRadialGradient(w / 2, h / 2, Math.min(w, h) * 0.2, w / 2, h / 2, Math.max(w, h) * 0.8);
vignetteGrad.addColorStop(0, 'rgba(0,0,0,0)');
vignetteGrad.addColorStop(0.6, 'rgba(0,0,0,0.6)');
vignetteGrad.addColorStop(1, 'rgba(0,0,0,0.95)');
ctx.fillStyle = vignetteGrad;
ctx.fillRect(0, 0, w, h);
// Load classic horror typographic font (Cinzel) using Google Fonts
await new Promise((resolve) => {
const link = document.createElement('link');
link.href = 'https://fonts.googleapis.com/css2?family=Cinzel:wght@600&display=swap';
link.rel = 'stylesheet';
document.head.appendChild(link);
link.onload = () => {
if (document.fonts) {
document.fonts.load('600 10px "Cinzel"').then(resolve).catch(resolve);
} else {
setTimeout(resolve, 800); // Fallback timeout if API is unavailable
}
};
link.onerror = resolve; // Continue even if font loading fails
});
// Formatting rules and placement
const baseSize = Math.min(w, h);
ctx.textAlign = "center";
ctx.textBaseline = "middle";
// Setup glow effect (common for titles on dark horror backgrounds)
ctx.shadowColor = 'rgba(255, 255, 255, 0.5)';
ctx.shadowBlur = baseSize * 0.02;
// Draw Main Title
const titleSize = Math.floor(baseSize * 0.1);
ctx.font = `600 ${titleSize}px "Cinzel", serif`;
ctx.fillStyle = "rgba(255, 255, 255, 0.95)";
const titleY = h * 0.75;
ctx.fillText(title, w / 2, titleY);
// Draw Subtitle (The Devil Made Me Do It)
ctx.shadowBlur = baseSize * 0.01;
const subSize = Math.floor(baseSize * 0.035);
// Add letter spacing if supported to give it that suspenseful layout
if ('letterSpacing' in ctx) {
ctx.letterSpacing = `${Math.floor(baseSize * 0.008)}px`;
}
ctx.font = `600 ${subSize}px "Cinzel", serif`;
ctx.fillStyle = "rgba(220, 220, 220, 0.85)";
ctx.fillText(subtitle, w / 2, titleY + titleSize * 0.75);
// Clean up text effects & draw bottom credits styling
ctx.shadowBlur = 0;
if ('letterSpacing' in ctx) {
ctx.letterSpacing = "0px";
}
const creditSize = Math.max(10, Math.floor(baseSize * 0.015));
ctx.font = `${creditSize}px sans-serif`;
ctx.fillStyle = "rgba(255, 255, 255, 0.4)";
ctx.fillText("A JAMES WAN FILM • BASED ON THE CASE FILES OF ED & LORRAINE WARREN", w / 2, h * 0.95);
return canvas;
}
Apply Changes