You can edit the below JavaScript code to customize the image tool.
Apply Changes
async function processImage(originalImg, movieTitle = "THE AI AWAKENING", subtitleText = "Processing your request...", intensity = "1") {
// Dynamically load cinematic font from Google Fonts
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);
try {
await document.fonts.load('600 50px Cinzel');
} catch (e) {
console.warn("Font loading skipped or failed", e);
}
// Set canonical output dimensions for a 16:9 workspace (HD)
const width = 1920;
const height = 1080;
const canvas = document.createElement('canvas');
canvas.width = width;
canvas.height = height;
const ctx = canvas.getContext('2d');
// Widescreen layout constants
const barHeight = 140; // Cinematic 2.35:1 letterbox simulation on 16:9
const frameY = barHeight;
const frameHeight = height - (barHeight * 2);
// Calculate crop for object-fit: cover inside the cinematic frame
const imgRatio = originalImg.width / originalImg.height;
const frameRatio = width / frameHeight;
let sx, sy, sWidth, sHeight;
if (imgRatio > frameRatio) {
sHeight = originalImg.height;
sWidth = sHeight * frameRatio;
sx = (originalImg.width - sWidth) / 2;
sy = 0;
} else {
sWidth = originalImg.width;
sHeight = sWidth / frameRatio;
sx = 0;
sy = (originalImg.height - sHeight) / 2;
}
// Draw the scaled and cropped original image
ctx.drawImage(originalImg, sx, sy, sWidth, sHeight, 0, frameY, width, frameHeight);
// Apply Cinematic Color Grading (Teal and Orange) + Contrast
const gradeIntensity = parseFloat(intensity) || 1;
const imgData = ctx.getImageData(0, frameY, width, frameHeight);
const data = imgData.data;
for (let i = 0; i < data.length; i += 4) {
let r = data[i];
let g = data[i + 1];
let b = data[i + 2];
// Boost Contrast
r = ((r / 255 - 0.5) * 1.3 + 0.5) * 255;
g = ((g / 255 - 0.5) * 1.3 + 0.5) * 255;
b = ((b / 255 - 0.5) * 1.3 + 0.5) * 255;
// Calculate Luminance
let lum = 0.299 * r + 0.587 * g + 0.114 * b;
// Weight mixes for Shadows and Highlights
let shadowMix = Math.max(0, (128 - lum) / 128) * gradeIntensity;
let highMix = Math.max(0, (lum - 128) / 128) * gradeIntensity;
// Apply Orange to Highlights, Teal to Shadows
r += highMix * 45 - shadowMix * 30;
g += highMix * 15 + shadowMix * 10;
b -= highMix * 30 + shadowMix * 45;
// Clamp & Assign Values
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, frameY);
// Add Film Grain overlay
const grainCanvas = document.createElement('canvas');
grainCanvas.width = width;
grainCanvas.height = frameHeight;
const grainCtx = grainCanvas.getContext('2d');
const grainData = grainCtx.createImageData(width, frameHeight);
for (let i = 0; i < grainData.data.length; i += 4) {
const val = Math.random() * 255;
grainData.data[i] = val;
grainData.data[i + 1] = val;
grainData.data[i + 2] = val;
grainData.data[i + 3] = 12; // Very subtle noise
}
grainCtx.putImageData(grainData, 0, 0);
ctx.drawImage(grainCanvas, 0, frameY);
// Apply Vignette overlay on the frame
const gradient = ctx.createRadialGradient(
width / 2, height / 2, 0,
width / 2, height / 2, width * 0.65
);
gradient.addColorStop(0, 'rgba(0,0,0,0)');
gradient.addColorStop(0.6, 'rgba(0,0,0,0.15)');
gradient.addColorStop(1, 'rgba(0,0,0,0.85)');
ctx.fillStyle = gradient;
ctx.fillRect(0, frameY, width, frameHeight);
// Draw Cinematic Letterboxing (Top & Bottom Black Bars)
ctx.fillStyle = '#000000';
ctx.fillRect(0, 0, width, barHeight); // Top
ctx.fillRect(0, height - barHeight, width, barHeight); // Bottom
// Apply Top Bar Movie Title
ctx.fillStyle = '#ffffff';
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.font = '600 45px Cinzel, serif';
if ('letterSpacing' in ctx) {
ctx.letterSpacing = '14px';
}
ctx.fillText(movieTitle.toUpperCase(), width / 2, barHeight / 2);
// Apply Bottom Bar Credits
ctx.font = '300 20px Arial, sans-serif';
if ('letterSpacing' in ctx) {
ctx.letterSpacing = '8px';
}
ctx.fillStyle = '#777777';
ctx.fillText("AI POWERED MOVIE CREATOR • GENERATED STILL • CINEMATIC EXPERIENCE", width / 2, height - (barHeight / 2));
// Draw Mock AI Camera / Recording UI
if ('letterSpacing' in ctx) ctx.letterSpacing = '1px';
ctx.font = '600 24px Courier New, monospace';
ctx.fillStyle = 'rgba(255, 255, 255, 0.75)';
ctx.textAlign = 'left';
ctx.textBaseline = 'bottom';
// Add pulsing red REC dot simulation
let dotX = 40;
let dotY = height - barHeight - 20;
ctx.fillStyle = '#ff0000';
ctx.beginPath();
ctx.arc(dotX, dotY - 10, 8, 0, Math.PI * 2);
ctx.fill();
ctx.fillStyle = 'rgba(255, 255, 255, 0.75)';
ctx.fillText(" REC • AI-SYS // 04:23:45:12", dotX + 15, dotY);
// Apply Subtitles (Bottom center of the frame)
if (subtitleText) {
if ('letterSpacing' in ctx) ctx.letterSpacing = '0px';
ctx.font = 'italic 600 50px Arial, sans-serif';
ctx.textAlign = 'center';
const subY = height - barHeight - 35; // Hover slightly above bottom black bar
ctx.strokeStyle = '#000000';
ctx.lineWidth = 7;
ctx.strokeText(subtitleText, width / 2, subY);
ctx.fillStyle = '#f5f5f5';
ctx.fillText(subtitleText, width / 2, subY);
}
return canvas;
}
Apply Changes