You can edit the below JavaScript code to customize the image tool.
Apply Changes
function processImage(originalImg, text = "TV LOGOS COMPILATION", cols = 3, rows = 2, enableScanlines = 1) {
// Parse and constrain the grid dimensions
const gridCols = Math.max(1, Math.min(10, parseInt(cols) || 3));
const gridRows = Math.max(1, Math.min(10, parseInt(rows) || 2));
const useScanlines = parseInt(enableScanlines) === 1;
// Create a standard YouTube-thumbnail-sized canvas for the compilation
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
const canvasWidth = 1280;
const canvasHeight = 720;
canvas.width = canvasWidth;
canvas.height = canvasHeight;
const cellWidth = canvasWidth / gridCols;
const cellHeight = canvasHeight / gridRows;
// Vibrant background colors typical for logo compilations
const bgColors = [
'#FF3333', '#3385FF', '#33FF33', '#FF9933',
'#FF33FF', '#33FFFF', '#FFE633', '#9933FF',
'#FF3399', '#33FF99', '#3333FF', '#99FF33',
'#FF6633', '#33CCFF', '#CCFF33', '#CC33FF'
];
let colorIndex = 0;
// Draw the Logo Compilation Grid
for (let r = 0; r < gridRows; r++) {
for (let c = 0; c < gridCols; c++) {
// Fill background cell
ctx.fillStyle = bgColors[colorIndex % bgColors.length];
ctx.fillRect(c * cellWidth, r * cellHeight, cellWidth, cellHeight);
// Add cell inner shadow / vignette-ish frame
ctx.strokeStyle = 'rgba(0, 0, 0, 0.4)';
ctx.lineWidth = 6;
ctx.strokeRect(c * cellWidth, r * cellHeight, cellWidth, cellHeight);
// Calculate image dimensions to fit within the grid cell with some padding
const padding = Math.min(cellWidth, cellHeight) * 0.15;
const maxImgW = cellWidth - padding * 2;
const maxImgH = cellHeight - padding * 2;
const imgAspect = originalImg.width / originalImg.height;
const cellAspect = maxImgW / maxImgH;
let drawW, drawH;
if (imgAspect > cellAspect) {
drawW = maxImgW;
drawH = maxImgW / imgAspect;
} else {
drawH = maxImgH;
drawW = maxImgH * imgAspect;
}
const drawX = c * cellWidth + (cellWidth - drawW) / 2;
const drawY = r * cellHeight + (cellHeight - drawH) / 2;
// Draw image with a drop shadow to make the "logo" pop
ctx.save();
ctx.shadowColor = 'rgba(0, 0, 0, 0.7)';
ctx.shadowBlur = 12;
ctx.shadowOffsetX = 6;
ctx.shadowOffsetY = 6;
// Optionally, we could add a white border around the image if needed,
// but for generic transparency logos, drawing it directly acts as a stylized layer.
ctx.drawImage(originalImg, drawX, drawY, drawW, drawH);
ctx.restore();
colorIndex++;
}
}
// Apply Retro TV Scanlines Over the Grid
if (useScanlines) {
ctx.save();
ctx.fillStyle = 'rgba(0, 0, 0, 0.15)';
ctx.globalCompositeOperation = 'multiply';
for (let i = 0; i < canvasHeight; i += 4) {
ctx.fillRect(0, i, canvasWidth, 2);
}
ctx.restore();
}
// Overlay bold, impact-style text at the bottom to give the "Compilation Video" vibe
if (text && text.trim().length > 0) {
ctx.save();
// Large dramatic font
const fontSize = 80;
ctx.font = `900 ${fontSize}px "Arial Black", Impact, sans-serif`;
ctx.textAlign = 'center';
ctx.textBaseline = 'bottom';
const textX = canvasWidth / 2;
const textY = canvasHeight - 30;
// Apply a thick black shadow and stroke behind the text
ctx.shadowColor = 'rgba(0, 0, 0, 0.8)';
ctx.shadowBlur = 20;
ctx.shadowOffsetX = 0;
ctx.shadowOffsetY = 10;
ctx.lineWidth = 14;
ctx.strokeStyle = '#000000';
ctx.lineJoin = 'round';
ctx.strokeText(text, textX, textY);
// Fill text with a vibrant Yellow-to-Orange gradient
ctx.shadowColor = 'transparent'; // Remove secondary shadow for fill itself
const gradient = ctx.createLinearGradient(0, textY - fontSize, 0, textY);
gradient.addColorStop(0, '#FFFF00'); // Bright yellow
gradient.addColorStop(1, '#FF6600'); // Deep orange
ctx.fillStyle = gradient;
ctx.fillText(text, textX, textY);
// Add a top inner white highlight to the text for a 3D bubble effect
ctx.lineWidth = 2;
ctx.strokeStyle = 'rgba(255, 255, 255, 0.6)';
ctx.strokeText(text, textX, textY - 2);
ctx.restore();
}
return canvas;
}
Apply Changes