Please bookmark this page to avoid losing your image tool!

The Conjuring Movie Poster Image Creator

(Free & Supports Bulk Upload)

Drag & drop your images here or

The result will appear here...
You can edit the below JavaScript code to customize the image tool.
async function processImage(
    originalImg, 
    title = "THE CONJURING", 
    subtitle = "BASED ON THE TRUE CASE FILES OF THE WARRENS", 
    releaseText = "IN THEATERS EVERYWHERE",
    colorTone = "cyan" // "cyan", "sepia", or "dark"
) {
    // 1. Intercept and load Google Fonts dynamically (Cinzel for title, Montserrat for modern clean text)
    const fontId = 'movie-poster-fonts';
    if (!document.getElementById(fontId)) {
        const link = document.createElement('link');
        link.id = fontId;
        link.rel = 'stylesheet';
        link.href = 'https://fonts.googleapis.com/css2?family=Cinzel:wght@700&family=Montserrat:wght@400;700&display=swap';
        document.head.appendChild(link);
        
        // Wait for CSS to load
        await new Promise(resolve => {
            link.onload = resolve;
            link.onerror = resolve; // proceed on error gracefully
        });
        
        // Wait for fonts to be parsed and ready in the document
        if (document.fonts && document.fonts.ready) {
            await document.fonts.ready;
        }
        // Small buffer to guarantee rendering
        await new Promise(r => setTimeout(r, 150));
    }

    // 2. Setup standard movie poster canvas (Aspect ratio 2:3)
    const w = 800;
    const h = 1200;
    const canvas = document.createElement('canvas');
    canvas.width = w;
    canvas.height = h;
    const ctx = canvas.getContext('2d');

    // 3. Draw and center-crop the original image to act as the cover background
    const scale = Math.max(w / originalImg.width, h / originalImg.height);
    const nw = originalImg.width * scale;
    const nh = originalImg.height * scale;
    const nx = (w - nw) / 2;
    const ny = (h - nh) / 2;

    // Apply eerie foundational filters (high contrast, de-saturated)
    ctx.filter = 'grayscale(80%) contrast(140%) brightness(70%)';
    ctx.drawImage(originalImg, nx, ny, nw, nh);
    ctx.filter = 'none'; // reset filter

    // 4. Color Grading (Cinematic Tint)
    // We add a multiplying color layer to give it the cold or murky ambiance
    ctx.globalCompositeOperation = 'multiply';
    if (colorTone.toLowerCase() === 'sepia') {
        ctx.fillStyle = '#4a4435'; // dark murky yellow/brown
    } else if (colorTone.toLowerCase() === 'cyan') {
        ctx.fillStyle = '#2d434a'; // dark cold slate blue/cyan
    } else {
        ctx.fillStyle = '#333333'; // basic dark
    }
    ctx.fillRect(0, 0, w, h);

    // Deepen shadows further
    ctx.globalCompositeOperation = 'overlay';
    ctx.fillStyle = 'rgba(0, 0, 0, 0.4)';
    ctx.fillRect(0, 0, w, h);
    ctx.globalCompositeOperation = 'source-over'; // reset

    // 5. Apply Vignettes & Shadows (Directing the light and preparing for text)
    // Dark radial vignette
    const rx = w / 2;
    const ry = h / 2;
    const gradRadial = ctx.createRadialGradient(rx, ry, h * 0.2, rx, ry, h * 0.8);
    gradRadial.addColorStop(0, 'rgba(0, 0, 0, 0)');
    gradRadial.addColorStop(0.6, 'rgba(0, 0, 0, 0.5)');
    gradRadial.addColorStop(1, 'rgba(0, 0, 0, 0.95)');
    ctx.fillStyle = gradRadial;
    ctx.fillRect(0, 0, w, h);

    // Top Linear Gradient (Ensures top subtitle is readable)
    const gradTop = ctx.createLinearGradient(0, 0, 0, h * 0.35);
    gradTop.addColorStop(0, 'rgba(0,0,0,0.85)');
    gradTop.addColorStop(1, 'rgba(0,0,0,0)');
    ctx.fillStyle = gradTop;
    ctx.fillRect(0, 0, w, h * 0.35);

    // Bottom Linear Gradient (Ensures main title and credits are readable)
    const gradBot = ctx.createLinearGradient(0, h, 0, h * 0.5);
    gradBot.addColorStop(0, 'rgba(0,0,0,0.95)');
    gradBot.addColorStop(1, 'rgba(0,0,0,0)');
    ctx.fillStyle = gradBot;
    ctx.fillRect(0, h * 0.5, w, h * 0.5);

    // 6. Generate Cinematic Film Grain overlay
    const noiseCanvas = document.createElement('canvas');
    noiseCanvas.width = 400; // Generate smaller noise map then scale up for performance & chunkier grain
    noiseCanvas.height = 600;
    const nCtx = noiseCanvas.getContext('2d');
    const nData = nCtx.createImageData(noiseCanvas.width, noiseCanvas.height);
    for (let i = 0; i < nData.data.length; i += 4) {
        const val = Math.random() * 255;
        nData.data[i] = val;
        nData.data[i+1] = val;
        nData.data[i+2] = val;
        nData.data[i+3] = 18; // Subdued opacity for the grain
    }
    nCtx.putImageData(nData, 0, 0);
    ctx.globalCompositeOperation = 'overlay';
    ctx.drawImage(noiseCanvas, 0, 0, w, h);
    ctx.globalCompositeOperation = 'source-over'; // reset

    // 7. Render Typography
    ctx.textAlign = 'center';
    ctx.textBaseline = 'middle';
    ctx.shadowColor = 'rgba(0, 0, 0, 0.9)';
    ctx.shadowBlur = 15;
    ctx.shadowOffsetY = 4;

    // Helper function to auto-scale font size
    const drawText = (text, startSize, fontFm, yPos, color, lSpacing) => {
        if ('letterSpacing' in ctx) {
            ctx.letterSpacing = lSpacing;
        }
        let fSize = startSize;
        ctx.font = `700 ${fSize}px "${fontFm}", sans-serif`;
        // Check overflow
        while (ctx.measureText(text).width > w - 60 && fSize > 12) {
            fSize -= 2;
            ctx.font = `700 ${fSize}px "${fontFm}", sans-serif`;
        }
        ctx.fillStyle = color;
        ctx.fillText(text, w / 2, yPos);
        // Clean letter-spacing for generic environment resets just in case
        if ('letterSpacing' in ctx) {
            ctx.letterSpacing = '0px';
        }
    };

    // Subtitle rendering (Top)
    drawText(subtitle, 24, "Montserrat", h * 0.12, "#c4c4c4", "8px");

    // Main Title rendering (Mid-Bottom)
    // Simulating distressed aged white/yellow text
    drawText(title, 95, "Cinzel", h * 0.72, "#ececdb", "12px");

    // Release Text rendering (Bottom)
    drawText(releaseText, 22, "Montserrat", h * 0.84, "#bd2626", "6px"); // Eerie deeply saturated red

    // 8. Add Faux Billing Block / Credits to complete the poster illusion
    ctx.shadowBlur = 8;
    ctx.shadowOffsetY = 2;
    const credits1 = "PRODUCED BY PETER SAFRAN  DIRECTED BY JAMES WAN";
    const credits2 = "MUSIC BY JOSEPH BISHARA  WRITTEN BY CHAD HAYES & CAREY W. HAYES";
    drawText(credits1, 12, "Montserrat", h * 0.92, "#888888", "2px");
    drawText(credits2, 12, "Montserrat", h * 0.945, "#888888", "2px");

    return canvas;
}

Free Image Tool Creator

Can't find the image tool you're looking for?
Create one based on your own needs now!

Description

The Conjuring Movie Poster Image Creator allows you to transform any uploaded image into a cinematic horror-style movie poster. The tool applies eerie visual effects such as high contrast, desaturation, color grading (in cyan, sepia, or dark tones), vignetting, and film grain to create a spooky atmosphere. It also automatically overlays stylized typography, including a main title, subtitle, release text, and a professional-looking credits block. This tool is ideal for fans of horror movies, content creators looking for dramatic social media assets, or anyone wanting to create fun, personalized movie-themed graphics.

Leave a Reply

Your email address will not be published. Required fields are marked *