Please bookmark this page to avoid losing your image tool!

Movie Style Image Creator For 9:16 Aspect Ratio

(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.
function processImage(originalImg, fillMode = "blur-bg", colorGrading = "teal-orange", vignetteStrength = 0.6, subtitleText = "") {
    // 9:16 Aspect Ratio Dimensions (Standard 1080x1920 for vertical movie formats like TikTok/Reels)
    const targetW = 1080;
    const targetH = 1920;

    const canvas = document.createElement("canvas");
    canvas.width = targetW;
    canvas.height = targetH;
    const ctx = canvas.getContext("2d", { willReadFrequently: true });

    const ow = originalImg.width;
    const oh = originalImg.height;

    // 1. Draw Background
    if (fillMode === "blur-bg") {
        ctx.fillStyle = "#000000";
        ctx.fillRect(0, 0, targetW, targetH);
        
        // Scale to cover
        let scaleCover = Math.max(targetW / ow, targetH / oh);
        let wCover = ow * scaleCover;
        let hCover = oh * scaleCover;
        
        ctx.filter = "blur(45px) brightness(0.4)";
        ctx.drawImage(originalImg, (targetW - wCover) / 2, (targetH - hCover) / 2, wCover, hCover);
        ctx.filter = "none";
    } else {
        // "black-bars" or other options
        ctx.fillStyle = "#000000";
        ctx.fillRect(0, 0, targetW, targetH);
    }

    // 2. Draw Main Image Focus
    if (fillMode === "crop") {
        let scaleCover = Math.max(targetW / ow, targetH / oh);
        let wCover = ow * scaleCover;
        let hCover = oh * scaleCover;
        ctx.drawImage(originalImg, (targetW - wCover) / 2, (targetH - hCover) / 2, wCover, hCover);
    } else {
        // Draw centered maintaining original aspect ratio
        let scaleContain = Math.min(targetW / ow, targetH / oh);
        let wContain = ow * scaleContain;
        let hContain = oh * scaleContain;
        ctx.drawImage(originalImg, (targetW - wContain) / 2, (targetH - hContain) / 2, wContain, hContain);
    }

    // 3. Apply Cinematic Color Grading (Pixel Manipulation)
    if (colorGrading !== "none") {
        const imgData = ctx.getImageData(0, 0, targetW, targetH);
        const data = imgData.data;

        // Contrast adjustment multiplier
        const contrastLevel = 35; 
        const factor = (259 * (contrastLevel + 255)) / (255 * (259 - contrastLevel));

        for (let i = 0; i < data.length; i += 4) {
            let r = data[i];
            let g = data[i+1];
            let b = data[i+2];

            // Increase Contrast to simulate dramatic movie look
            r = factor * (r - 128) + 128;
            g = factor * (g - 128) + 128;
            b = factor * (b - 128) + 128;

            if (colorGrading === "teal-orange") {
                // Calculate Luminance
                let luma = 0.299 * r + 0.587 * g + 0.114 * b;
                
                // -1 (shadows) to +1 (highlights)
                let mix = (luma - 128) / 128; 

                if (mix > 0) {
                    // Highlights -> Warmer (Orange tint)
                    r += mix * 35;
                    g += mix * 10;
                    b -= mix * 30;
                } else {
                    // Shadows -> Cooler (Teal tint)
                    // mix is negative, so adding mix subtracts the value
                    r += mix * 40;       // Drops red
                    b -= mix * 45;       // Increases blue (double negative)
                    g -= mix * 20;       // Increases green slightly, yielding teal
                }
            } else if (colorGrading === "vintage") {
                // Sepia conversion
                let tr = 0.393 * r + 0.769 * g + 0.189 * b;
                let tg = 0.349 * r + 0.686 * g + 0.168 * b;
                let tb = 0.272 * r + 0.534 * g + 0.131 * b;
                r = tr; g = tg; b = tb;
            }

            // Add subtle cinematic film grain
            let grain = (Math.random() - 0.5) * 12;
            r += grain;
            g += grain;
            b += grain;

            // Clamp values between 0 and 255
            data[i] = Math.min(255, Math.max(0, r));
            data[i+1] = Math.min(255, Math.max(0, g));
            data[i+2] = Math.min(255, Math.max(0, b));
        }
        ctx.putImageData(imgData, 0, 0);
    }

    // 4. Apply Vignette (Darkened Edges)
    if (vignetteStrength > 0) {
        let maxDim = Math.max(targetW, targetH);
        let gradient = ctx.createRadialGradient(
            targetW / 2, targetH / 2, maxDim * 0.3, 
            targetW / 2, targetH / 2, maxDim * 0.7
        );
        gradient.addColorStop(0, "rgba(0,0,0,0)");
        gradient.addColorStop(1, `rgba(0,0,0,${Math.min(vignetteStrength, 1)})`);
        ctx.fillStyle = gradient;
        ctx.fillRect(0, 0, targetW, targetH);
    }

    // 5. Draw Optional Cinematic Subtitle
    if (subtitleText && subtitleText.trim() !== "") {
        const fontSize = 48;
        ctx.font = `italic ${fontSize}px Arial, sans-serif`;
        ctx.textAlign = "center";
        ctx.textBaseline = "middle";
        
        // Movie Subtitle Shadow/Stroke Effect
        ctx.shadowColor = "rgba(0,0,0,1)";
        ctx.shadowBlur = 10;
        ctx.shadowOffsetX = 3;
        ctx.shadowOffsetY = 3;
        
        ctx.fillStyle = "#f1c40f"; // Standard cinematic yellow for readability

        // Basic multi-line word wrapping logic
        const words = subtitleText.split(" ");
        let line = "";
        let lines = [];
        for(let n = 0; n < words.length; n++) {
            let testLine = line + words[n] + " ";
            if(ctx.measureText(testLine).width > targetW * 0.85 && n > 0) {
                lines.push(line);
                line = words[n] + " ";
            } else {
                line = testLine;
            }
        }
        lines.push(line);

        // Position text near the bottom quarter
        let startY = targetH * 0.85;
        for(let i = 0; i < lines.length; i++) {
            ctx.fillText(lines[i], targetW / 2, startY + (i * fontSize * 1.3));
        }

        // Reset shadow
        ctx.shadowBlur = 0;
        ctx.shadowOffsetX = 0;
        ctx.shadowOffsetY = 0;
    }

    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

This tool transforms standard images into cinematic, vertical-format visuals optimized for a 9:16 aspect ratio, making them ideal for social media platforms like TikTok, Instagram Reels, and YouTube Shorts. Users can convert their photos by applying professional color grading presets such as ‘teal and orange’ or ‘vintage’ styles, adding film grain, and applying a vignette effect to draw focus to the center. The tool also provides options for background filling—including a blurred background effect to prevent black bars—and allows users to add stylized, movie-style subtitles to create a dramatic, filmic atmosphere.

Leave a Reply

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