You can edit the below JavaScript code to customize the image tool.
Apply Changes
async function processImage(originalImg, wantedText = 'WANTED', subheadingText = 'DEAD OR ALIVE', nameText = 'NAME GOES HERE', rewardText = '$10,000 REWARD') {
// We make it an async function to dynamically load the required font.
const fontName = 'Rye';
try {
const font = new FontFace(fontName, `url(https://fonts.gstatic.com/s/rye/v22/r05XGLl7_y1_3JAbVxc.woff2)`);
await font.load();
document.fonts.add(font);
} catch (e) {
// Log an error if the font cannot be loaded, but continue with a fallback.
console.error(`Font '${fontName}' could not be loaded. Using system default 'serif'.`, e);
}
// --- 1. Calculate Dimensions ---
// The canvas width is fixed, and the height adjusts to the image's aspect ratio.
const canvasWidth = 600;
const padding = 50;
const contentWidth = canvasWidth - 2 * padding;
const imgAspectRatio = originalImg.height / originalImg.width;
const imgHeight = contentWidth * imgAspectRatio;
// Define heights for the text sections above and below the image.
const topSectionHeight = 150;
const bottomSectionHeight = 220;
const canvasHeight = topSectionHeight + imgHeight + bottomSectionHeight;
// --- 2. Create Canvas and Context ---
const canvas = document.createElement('canvas');
canvas.width = canvasWidth;
canvas.height = canvasHeight;
const ctx = canvas.getContext('2d');
// --- 3. Draw Background ---
// Fill with a base "aged paper" color.
ctx.fillStyle = '#f3e9d2';
ctx.fillRect(0, 0, canvasWidth, canvasHeight);
// Add subtle, random splotches for a more authentic, aged look.
const darkBrown = 'rgba(64, 42, 42, 0.05)';
for (let i = 0; i < 150; i++) {
const x = Math.random() * canvas.width;
const y = Math.random() * canvas.height;
// Using Math.random() twice skews the distribution towards smaller radii.
const radius = Math.random() * Math.random() * 80;
const grad = ctx.createRadialGradient(x, y, 0, x, y, radius);
grad.addColorStop(0, darkBrown);
grad.addColorStop(1, 'rgba(64, 42, 42, 0)');
ctx.fillStyle = grad;
ctx.beginPath();
ctx.arc(x, y, radius, 0, 2 * Math.PI);
ctx.fill();
}
// --- 4. Draw Text ---
const textColor = '#402a2a';
const primaryFont = `'${fontName}', serif`; // Use the loaded font with a fallback.
ctx.fillStyle = textColor;
ctx.textAlign = 'center';
// Draw "WANTED" at the top.
ctx.textBaseline = 'middle';
ctx.font = `bold 90px ${primaryFont}`;
ctx.fillText(wantedText.toUpperCase(), canvasWidth / 2, topSectionHeight / 2);
// --- 5. Draw Image ---
const imgX = padding;
const imgY = topSectionHeight;
// Draw a double border behind the image for a framed effect.
ctx.strokeStyle = '#2a1a19';
ctx.lineWidth = 1.5;
ctx.strokeRect(imgX - 6, imgY - 6, contentWidth + 12, imgHeight + 12);
ctx.lineWidth = 4;
ctx.strokeRect(imgX, imgY, contentWidth, imgHeight);
// Apply a sepia-like filter to the image to match the old-fashioned theme.
ctx.save();
ctx.filter = 'sepia(1) contrast(1.1) brightness(0.9)';
ctx.drawImage(originalImg, imgX, imgY, contentWidth, imgHeight);
ctx.restore();
// --- 6. Draw Bottom Text ---
ctx.textBaseline = 'top';
const bottomTextYStart = topSectionHeight + imgHeight;
// Draw "DEAD OR ALIVE"
ctx.font = `30px ${primaryFont}`;
ctx.fillText(subheadingText.toUpperCase(), canvasWidth / 2, bottomTextYStart + 50);
// Draw the name
ctx.font = `55px ${primaryFont}`;
ctx.fillText(nameText.toUpperCase(), canvasWidth / 2, bottomTextYStart + 95);
// Draw the reward
ctx.font = `35px ${primaryFont}`;
ctx.fillText(rewardText.toUpperCase(), canvasWidth / 2, bottomTextYStart + 165);
// Finally, return the completed canvas.
return canvas;
}
Apply Changes