You can edit the below JavaScript code to customize the image tool.
Apply Changes
async function processImage(originalImg, studioName = "A.I. CINEMA", subtitle = "RELEASING", style = "gold") {
// Create a canvas based on the original image dimensions
const canvas = document.createElement('canvas');
canvas.width = originalImg.width;
canvas.height = originalImg.height;
const ctx = canvas.getContext('2d');
// 1. Draw the beautiful background image
ctx.drawImage(originalImg, 0, 0, canvas.width, canvas.height);
// 2. Add a cinematic vignette to focus attention on the center text
const vignette = ctx.createRadialGradient(
canvas.width / 2, canvas.height / 2, canvas.width * 0.1,
canvas.width / 2, canvas.height / 2, canvas.width * 0.8
);
vignette.addColorStop(0, 'rgba(0,0,0,0)');
vignette.addColorStop(1, 'rgba(0,0,0,0.7)');
ctx.fillStyle = vignette;
ctx.fillRect(0, 0, canvas.width, canvas.height);
// 3. Add ultra-wide aspect ratio black bars (2.35:1) if the original image is narrower
const targetRatio = 2.35;
const imgRatio = canvas.width / canvas.height;
if (imgRatio < targetRatio) {
const barHeight = (canvas.height - (canvas.width / targetRatio)) / 2;
ctx.fillStyle = '#000000';
ctx.fillRect(0, 0, canvas.width, barHeight);
ctx.fillRect(0, canvas.height - barHeight, canvas.width, barHeight);
}
// 4. Calculate dynamic font sizes to ensure text fits the canvas
const centerX = canvas.width / 2;
// Base main text size loosely on canvas width and text length
let mainFontSize = canvas.width / (Math.max(studioName.length, 5) * 0.6);
if (mainFontSize > canvas.height / 4) mainFontSize = canvas.height / 4; // limit max size
let subFontSize = canvas.width / (Math.max(subtitle.length, 5) * 0.8);
if (subFontSize > mainFontSize * 0.4) subFontSize = mainFontSize * 0.4;
// Layout centers
const textCenterY = canvas.height / 2;
const mainY = textCenterY - (subFontSize / 2);
const subY = textCenterY + (mainFontSize * 0.6);
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.lineJoin = 'round'; // rounded corners on text strokes
// 5. Render Text Based on the Selected Style
if (style.toLowerCase() === 'gold') {
// --- GOLDEN 3D MONUMENT STYLE (20th Century / Blockbuster style) ---
ctx.font = `italic bold ${mainFontSize}px Impact, "Arial Black", sans-serif`;
const depth = mainFontSize * 0.08;
// Shadow for the whole 3D object
ctx.shadowColor = 'rgba(0,0,0,0.9)';
ctx.shadowBlur = 20;
ctx.shadowOffsetX = 15;
ctx.shadowOffsetY = 15;
ctx.fillText(studioName, centerX - depth, mainY + depth); // Draw an invisible base just for shadow
// Turn off canvas shadow for the solid extrusion
ctx.shadowColor = 'transparent';
ctx.shadowBlur = 0;
ctx.shadowOffsetX = 0;
ctx.shadowOffsetY = 0;
// 3D Extrusion (Back to Front)
for (let i = depth; i > 0; i -= 1.5) {
// Give a darker bronze/copper gradient for the sides
let sideGrad = ctx.createLinearGradient(0, mainY - mainFontSize, 0, mainY + mainFontSize);
sideGrad.addColorStop(0, '#59430b');
sideGrad.addColorStop(0.5, '#4a3600');
sideGrad.addColorStop(1, '#2a1e00');
ctx.fillStyle = sideGrad;
// Draw slightly shifted text
ctx.fillText(studioName, centerX - i, mainY + i);
ctx.lineWidth = 1;
ctx.strokeStyle = '#221500';
ctx.strokeText(studioName, centerX - i, mainY + i);
}
// Front Face Gradient (Shiny Gold)
const frontGrad = ctx.createLinearGradient(0, mainY - mainFontSize*0.4, 0, mainY + mainFontSize*0.4);
frontGrad.addColorStop(0, '#fffacd'); // LemonChiffon
frontGrad.addColorStop(0.3, '#ffdf00'); // Light Gold
frontGrad.addColorStop(0.45, '#d4af37'); // Metallic Gold
frontGrad.addColorStop(0.55, '#8b6508'); // Dark Gold
frontGrad.addColorStop(0.7, '#ffdf00');
frontGrad.addColorStop(1, '#b8860b'); // GoldenRod
ctx.fillStyle = frontGrad;
ctx.strokeStyle = '#ffffff';
ctx.lineWidth = Math.max(1, mainFontSize * 0.005);
ctx.fillText(studioName, centerX, mainY);
ctx.strokeText(studioName, centerX, mainY);
// Subtitle text (Solid gold, glowing)
ctx.font = `bold ${subFontSize}px Arial, sans-serif`;
if ('letterSpacing' in ctx) ctx.letterSpacing = `${subFontSize * 0.4}px`;
ctx.fillStyle = '#ffdf00';
ctx.shadowColor = 'rgba(0, 0, 0, 0.9)';
ctx.shadowBlur = 10;
ctx.shadowOffsetX = 3;
ctx.shadowOffsetY = 3;
ctx.fillText(subtitle, centerX, subY);
} else if (style.toLowerCase() === 'classic') {
// --- CLASSIC ELEGANT STYLE (Classic Hollywood Era) ---
ctx.font = `normal ${mainFontSize}px "Times New Roman", Times, serif`;
ctx.fillStyle = '#ffffff';
ctx.shadowColor = 'rgba(0, 0, 0, 0.8)';
ctx.shadowBlur = 25;
ctx.shadowOffsetX = 0;
ctx.shadowOffsetY = mainFontSize * 0.05;
ctx.fillText(studioName, centerX, mainY);
// Classic subtitle with elegant wide spacing
ctx.font = `italic ${subFontSize}px Georgia, "Times New Roman", serif`;
if ('letterSpacing' in ctx) ctx.letterSpacing = `${subFontSize * 0.3}px`;
// Add thin lines around subtitle
ctx.fillText(subtitle, centerX, subY);
// Decorative lines for classic feel
ctx.shadowColor = 'transparent';
ctx.strokeStyle = '#ffffff';
ctx.lineWidth = Math.max(1, subFontSize * 0.05);
const lineLen = ctx.measureText(subtitle).width * 0.6 || (canvas.width * 0.3);
ctx.beginPath();
ctx.moveTo(centerX - lineLen, subY + subFontSize);
ctx.lineTo(centerX + lineLen, subY + subFontSize);
ctx.stroke();
} else {
// --- NEON / SYNTHWAVE STYLE (80s Action/Sci-Fi) ---
ctx.font = `italic bold ${mainFontSize}px "Courier New", Courier, monospace`;
// Add a darker blue/purple cinematic overlay to make neon pop
ctx.fillStyle = 'rgba(5, 0, 20, 0.5)';
ctx.fillRect(0, 0, canvas.width, canvas.height);
// Main Text Neon (Magenta)
ctx.shadowColor = '#ff00ff';
ctx.shadowBlur = mainFontSize * 0.25;
ctx.fillStyle = '#ffffff';
ctx.strokeStyle = '#ff00ff';
ctx.lineWidth = Math.max(2, mainFontSize * 0.02);
// Draw multiple times to overlay neon glow intensity
for(let i=0; i<3; i++) {
ctx.fillText(studioName, centerX, mainY);
ctx.strokeText(studioName, centerX, mainY);
}
// Subtitle Neon (Cyan)
ctx.font = `bold ${subFontSize}px "Consolas", "Courier New", monospace`;
if ('letterSpacing' in ctx) ctx.letterSpacing = `${subFontSize * 0.5}px`;
ctx.shadowColor = '#00ffff';
ctx.strokeStyle = '#00ffff';
ctx.shadowBlur = subFontSize * 0.4;
ctx.lineWidth = Math.max(1, subFontSize * 0.03);
for(let i=0; i<3; i++) {
ctx.fillText(subtitle, centerX, subY);
ctx.strokeText(subtitle, centerX, subY);
}
}
// Reset standard letter pacing for future strokes
if ('letterSpacing' in ctx) ctx.letterSpacing = '0px';
return canvas;
}
Apply Changes