You can edit the below JavaScript code to customize the image tool.
Apply Changes
function processImage(originalImg, movieTitle = 'Inception', year = '2010', rating = '8.8', genre = 'Action, Adventure, Sci-Fi', director = 'Christopher Nolan') {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
const width = originalImg.width;
const height = originalImg.height;
// Maintain the original image dimensions
canvas.width = width;
canvas.height = height;
// Draw original image on the canvas
ctx.drawImage(originalImg, 0, 0, width, height);
// Calculate dynamic base sizing according to the image dimensions
const refDim = Math.min(width, height);
const padding = refDim * 0.05;
const fSizeSmallX = Math.max(refDim * 0.025, 12);
const fSizeSmall = Math.max(refDim * 0.035, 16);
const fSizeMedium = Math.max(refDim * 0.045, 20);
const fSizeLarge = Math.max(refDim * 0.07, 28);
// Context helper configuration for line wrap
ctx.font = `bold ${fSizeLarge}px Arial`;
const maxTitleWidth = width - padding * 2;
function wrapText(text, maxWidth) {
let words = String(text).split(' ');
let lines = [];
let currentLine = words[0];
for (let i = 1; i < words.length; i++) {
let word = words[i];
let testWidth = ctx.measureText(currentLine + " " + word).width;
if (testWidth < maxWidth) {
currentLine += " " + word;
} else {
lines.push(currentLine);
currentLine = word;
}
}
lines.push(currentLine);
return lines;
}
// Determine lines of text and overall text placement requirements
const titleLines = wrapText(movieTitle, maxTitleWidth).reverse();
const logoHeight = fSizeMedium * 1.5;
let totalTextHeight = padding;
totalTextHeight += fSizeSmallX * 1.5; // Director line
totalTextHeight += fSizeSmall * 1.5; // Genre line
totalTextHeight += logoHeight; // IMDb Logo & Rating line
totalTextHeight += fSizeLarge * 0.3; // Gap
totalTextHeight += titleLines.length * fSizeLarge * 1.1; // Title lines
// Create a smooth bottom-to-top gradient background mask for high contrast text readability
const gradientTop = Math.max(0, height - totalTextHeight - height * 0.2);
const gradient = ctx.createLinearGradient(0, gradientTop, 0, height);
gradient.addColorStop(0, 'rgba(0,0,0,0)');
gradient.addColorStop(0.35, 'rgba(0,0,0,0.6)');
gradient.addColorStop(1, 'rgba(0,0,0,0.95)');
ctx.fillStyle = gradient;
ctx.fillRect(0, gradientTop, width, height - gradientTop);
// Start drawing text from the bottom upward
let currentY = height - padding;
// Apply a light shadow to text
ctx.shadowColor = "rgba(0,0,0,0.8)";
ctx.shadowBlur = 4;
ctx.shadowOffsetX = 1;
ctx.shadowOffsetY = 1;
// 1. Director Segment
ctx.font = `${fSizeSmallX}px Arial`;
ctx.fillStyle = "#bbbbbb";
ctx.fillText("Director:", padding, currentY);
let dirLabelWidth = ctx.measureText("Director: ").width;
ctx.fillStyle = "#ffffff";
ctx.fillText(String(director), padding + dirLabelWidth, currentY);
currentY -= fSizeSmallX * 1.5;
// 2. Genre Segment
ctx.font = `${fSizeSmall}px Arial`;
ctx.fillStyle = "#dddddd";
ctx.fillText(String(genre), padding, currentY);
currentY -= fSizeSmall * 1.5;
// Turn off shadow for IMDb logo rendering
ctx.shadowBlur = 0;
ctx.shadowOffsetX = 0;
ctx.shadowOffsetY = 0;
// 3. IMDb Logo, Rating and Year Segment
const logoWidth = fSizeMedium * 2.5;
const logoStartY = currentY - logoHeight * 0.85;
// Draw rounded background block for "IMDb"
ctx.fillStyle = "#f5c518"; // Classic IMDb Yellow
const radius = logoHeight * 0.15;
ctx.beginPath();
ctx.moveTo(padding + radius, logoStartY);
ctx.lineTo(padding + logoWidth - radius, logoStartY);
ctx.quadraticCurveTo(padding + logoWidth, logoStartY, padding + logoWidth, logoStartY + radius);
ctx.lineTo(padding + logoWidth, logoStartY + logoHeight - radius);
ctx.quadraticCurveTo(padding + logoWidth, logoStartY + logoHeight, padding + logoWidth - radius, logoStartY + logoHeight);
ctx.lineTo(padding + radius, logoStartY + logoHeight);
ctx.quadraticCurveTo(padding, logoStartY + logoHeight, padding, logoStartY + logoHeight - radius);
ctx.lineTo(padding, logoStartY + radius);
ctx.quadraticCurveTo(padding, logoStartY, padding + radius, logoStartY);
ctx.closePath();
ctx.fill();
// "IMDb" Label inside the block
ctx.fillStyle = "#000000";
ctx.font = `900 ${fSizeMedium * 0.75}px 'Arial Black', Arial, sans-serif`;
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.fillText("IMDb", padding + logoWidth / 2, logoStartY + logoHeight / 2);
ctx.textAlign = "left";
// Star Graphic
const starRadius = fSizeMedium * 0.45;
const starX = padding + logoWidth + fSizeMedium * 1.2;
const starY = logoStartY + logoHeight / 2;
ctx.fillStyle = "#f5c518";
ctx.beginPath();
for (let i = 0; i < 5; i++) {
let rot1 = (Math.PI / 2 * 3) + (i * Math.PI * 2 / 5);
let rot2 = (Math.PI / 2 * 3) + ((i + 0.5) * Math.PI * 2 / 5);
ctx.lineTo(starX + Math.cos(rot1) * starRadius, starY + Math.sin(rot1) * starRadius);
ctx.lineTo(starX + Math.cos(rot2) * starRadius / 2, starY + Math.sin(rot2) * starRadius / 2);
}
ctx.closePath();
ctx.fill();
// Rating Number
ctx.shadowColor = "rgba(0,0,0,0.8)";
ctx.shadowBlur = 4;
ctx.shadowOffsetX = 1;
ctx.shadowOffsetY = 1;
ctx.fillStyle = "#ffffff";
ctx.font = `bold ${fSizeMedium}px Arial`;
const ratingTextX = starX + starRadius * 1.5;
ctx.fillText(String(rating), ratingTextX, starY);
// Disable shadow text effect for minor inline details (Year)
ctx.shadowBlur = 0;
ctx.shadowOffsetX = 0;
ctx.shadowOffsetY = 0;
const ratingWidth = ctx.measureText(String(rating)).width;
ctx.fillStyle = "#aaaaaa";
ctx.font = `${fSizeSmall}px Arial`;
ctx.fillText(String(year), ratingTextX + ratingWidth + fSizeMedium * 0.8, starY);
ctx.textBaseline = "alphabetic";
currentY = logoStartY - fSizeLarge * 0.3;
// 4. Movie Title Segment
ctx.shadowColor = "rgba(0,0,0,0.8)";
ctx.shadowBlur = 5;
ctx.shadowOffsetX = 2;
ctx.shadowOffsetY = 2;
ctx.fillStyle = "#ffffff";
ctx.font = `bold ${fSizeLarge}px Arial`;
// Write title upwards if multiline
for (let line of titleLines) {
ctx.fillText(line, padding, currentY);
currentY -= fSizeLarge * 1.1;
}
return canvas;
}
Apply Changes