You can edit the below JavaScript code to customize the image tool.
Apply Changes
function processImage(
originalImg,
linkUrl = 'https://example.com/software',
title = 'Software Title',
description = 'A brief description of this amazing software and its key features. It solves all your problems efficiently.',
buttonText = 'Learn More'
) {
// ---- 1. Configuration & Canvas Setup ----
const PADDING = 20;
const CANVAS_HEIGHT = 200;
const TEXT_BLOCK_WIDTH = 350;
const SPACING = 10;
const FONT_FAMILY = '"Segoe UI", Arial, sans-serif';
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
// ---- 2. Image Scaling & Canvas Sizing ----
const maxImgHeight = CANVAS_HEIGHT - 2 * PADDING;
// Don't scale up small images, only scale down large ones
const scale = Math.min(1, maxImgHeight / originalImg.height);
const imgWidth = originalImg.width * scale;
const imgHeight = originalImg.height * scale;
const canvasWidth = imgWidth + TEXT_BLOCK_WIDTH + 3 * PADDING;
canvas.width = canvasWidth;
canvas.height = CANVAS_HEIGHT;
// ---- 3. Drawing Background & Image ----
// A subtle gradient for a professional "software" look
const gradient = ctx.createLinearGradient(0, 0, 0, canvas.height);
gradient.addColorStop(0, '#f8f9fa');
gradient.addColorStop(1, '#e9ecef');
ctx.fillStyle = gradient;
ctx.fillRect(0, 0, canvas.width, canvas.height);
// Draw the scaled original image on the left, vertically centered
const imgX = PADDING;
const imgY = (canvas.height - imgHeight) / 2;
ctx.drawImage(originalImg, imgX, imgY, imgWidth, imgHeight);
ctx.strokeStyle = '#ced4da'; // Light gray border
ctx.lineWidth = 1;
ctx.strokeRect(imgX, imgY, imgWidth, imgHeight);
// ---- 4. Text & Button Layout ----
const textX = imgX + imgWidth + PADDING;
const textMaxWidth = TEXT_BLOCK_WIDTH - PADDING;
// --- Draw URL at the bottom ---
const urlY = canvas.height - PADDING;
ctx.fillStyle = '#6c757d'; // Muted gray text
ctx.font = `12px ${FONT_FAMILY}`;
ctx.fillText(linkUrl, textX, urlY);
// --- Draw Button above the URL ---
const buttonHeight = 40;
const buttonWidth = 160;
const buttonY = urlY - buttonHeight - SPACING;
const buttonX = textX;
ctx.fillStyle = '#007bff'; // Bootstrap primary blue
ctx.strokeStyle = '#0056b3'; // Darker blue for border
ctx.lineWidth = 1;
// Use built-in roundRect for modern browsers, with a fallback
if (ctx.roundRect) {
ctx.beginPath();
ctx.roundRect(buttonX, buttonY, buttonWidth, buttonHeight, 5);
ctx.fill();
ctx.stroke();
} else {
// Fallback for older browsers to draw a rounded rectangle
const r = 5;
ctx.beginPath();
ctx.moveTo(buttonX + r, buttonY);
ctx.lineTo(buttonX + buttonWidth - r, buttonY);
ctx.quadraticCurveTo(buttonX + buttonWidth, buttonY, buttonX + buttonWidth, buttonY + r);
ctx.lineTo(buttonX + buttonWidth, buttonY + buttonHeight - r);
ctx.quadraticCurveTo(buttonX + buttonWidth, buttonY + buttonHeight, buttonX + buttonWidth - r, buttonY + buttonHeight);
ctx.lineTo(buttonX + r, buttonY + buttonHeight);
ctx.quadraticCurveTo(buttonX, buttonY + buttonHeight, buttonX, buttonY + buttonHeight - r);
ctx.lineTo(buttonX, buttonY + r);
ctx.quadraticCurveTo(buttonX, buttonY, buttonX + r, buttonY);
ctx.closePath();
ctx.fill();
ctx.stroke();
}
ctx.fillStyle = '#ffffff'; // White button text
ctx.font = `bold 16px ${FONT_FAMILY}`;
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.fillText(buttonText, buttonX + buttonWidth / 2, buttonY + buttonHeight / 2);
// Reset text alignment for subsequent drawing
ctx.textAlign = 'left';
ctx.textBaseline = 'alphabetic';
// --- Draw Title at the top ---
let currentY = PADDING + 24; // Start Y position for title
ctx.fillStyle = '#212529'; // Very dark gray for title
ctx.font = `bold 24px ${FONT_FAMILY}`;
ctx.fillText(title, textX, currentY);
currentY += SPACING * 2;
// --- Draw Description with wrapping and truncation ---
const lineHeight = 18;
const availableHeightForDesc = buttonY - currentY - SPACING;
const maxLines = Math.floor(availableHeightForDesc / lineHeight);
if (maxLines > 0) {
let words = description.split(' ');
let lines = [];
let currentLine = words[0] || '';
ctx.fillStyle = '#495057'; // Medium gray for description
ctx.font = `14px ${FONT_FAMILY}`;
for (let i = 1; i < words.length; i++) {
let width = ctx.measureText(currentLine + " " + words[i]).width;
if (width < textMaxWidth) {
currentLine += " " + words[i];
} else {
lines.push(currentLine);
currentLine = words[i];
}
}
lines.push(currentLine);
// Truncate if too many lines
if (lines.length > maxLines) {
let lastLine = lines[maxLines - 1];
// Keep removing the last word until the line fits with an ellipsis
while(ctx.measureText(lastLine + '...').width > textMaxWidth && lastLine.includes(' ')) {
lastLine = lastLine.substring(0, lastLine.lastIndexOf(' '));
}
lines[maxLines-1] = lastLine.trim() + '...';
lines = lines.slice(0, maxLines);
}
// Render the processed lines
for (let i = 0; i < lines.length; i++) {
ctx.fillText(lines[i], textX, currentY);
currentY += lineHeight;
}
}
// ---- 5. Return The Final Canvas ----
return canvas;
}
Apply Changes