You can edit the below JavaScript code to customize the image tool.
Apply Changes
function processImage(originalImg,
locationText = "DESTINATION",
greetingText = "Greetings from",
topText = "SOUVENIR",
fontFamily = "cursive",
textColor = "#333333",
cardBackgroundColor = "#FFF8DC", // Cornsilk
imageMarginPx = 15, // Border around the image
imageMarginColor = "white",
outerPaddingPx = 25, // Padding for the whole card content
displayStamp = 1, // 0 for no, 1 for yes
stampDetailsColor = "#5A5A5A",
cardEdgeWidthPx = 2,
cardEdgeColor = "#D3D3D3" // LightGray
) {
const imgW = originalImg.width;
const imgH = originalImg.height;
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
// 1. Calculate dimensions
const spacing = outerPaddingPx * 0.5; // Spacing between elements
// Determine base height for text sections, ensuring it's not too small
const baseHeightUnitForText = Math.max(20, outerPaddingPx * 0.8);
const topTextSectionHeight = topText ? Math.max(30, baseHeightUnitForText * 1.2) : 0;
const bottomTextSectionHeight = (greetingText || locationText) ? Math.max(40, baseHeightUnitForText * 1.8) : 0;
canvas.width = imgW + (2 * imageMarginPx) + (2 * outerPaddingPx);
canvas.height = (2 * outerPaddingPx) +
topTextSectionHeight + (topTextSectionHeight > 0 ? spacing : 0) +
(imgH + 2 * imageMarginPx) +
((greetingText || locationText) ? spacing : 0) + bottomTextSectionHeight;
// 2. Draw card background
ctx.fillStyle = cardBackgroundColor;
ctx.fillRect(0, 0, canvas.width, canvas.height);
// 3. Draw card edge/border
if (cardEdgeWidthPx > 0) {
ctx.strokeStyle = cardEdgeColor;
ctx.lineWidth = cardEdgeWidthPx;
// Draw a rect slightly inset if border is thick, to ensure it's fully visible
const inset = cardEdgeWidthPx / 2;
ctx.strokeRect(
inset,
inset,
canvas.width - cardEdgeWidthPx,
canvas.height - cardEdgeWidthPx
);
}
let currentY = outerPaddingPx;
ctx.textAlign = "center";
ctx.textBaseline = "middle"; // Consistent baseline for easier vertical centering
// 4. Draw Top Text
if (topText) {
const fontSize = topTextSectionHeight * 0.6; // Font size is 60% of its allocated section height
ctx.font = `bold ${fontSize}px ${fontFamily}`;
ctx.fillStyle = textColor;
ctx.fillText(topText.toUpperCase(), canvas.width / 2, currentY + topTextSectionHeight / 2);
currentY += topTextSectionHeight + spacing;
}
// 5. Draw Image Area (image margin/border + image itself)
const imageAreaX = outerPaddingPx;
const imageAreaY = currentY;
const imageAreaWidth = imgW + 2 * imageMarginPx;
const imageAreaHeight = imgH + 2 * imageMarginPx;
// Draw image margin (which acts as a border around the image)
if (imageMarginPx > 0) {
ctx.fillStyle = imageMarginColor;
ctx.fillRect(imageAreaX, imageAreaY, imageAreaWidth, imageAreaHeight);
}
// Draw the actual image
ctx.drawImage(originalImg, imageAreaX + imageMarginPx, imageAreaY + imageMarginPx, imgW, imgH);
currentY += imageAreaHeight + spacing;
// 6. Draw Bottom Text (Greeting & Location)
if (greetingText || locationText) {
ctx.fillStyle = textColor;
if (greetingText && locationText) {
// Roughly allocate 45% height for greeting, 55% for location text
const greetingPartHeight = bottomTextSectionHeight * 0.45;
const locationPartHeight = bottomTextSectionHeight * 0.55;
const greetingFontSize = Math.max(10, greetingPartHeight * 0.7); // Use 70% of its part, min 10px
const locationFontSize = Math.max(12, locationPartHeight * 0.6); // Use 60% of its part, min 12px
const greetingY = currentY + greetingPartHeight / 2;
const locationY = currentY + greetingPartHeight + locationPartHeight / 2;
ctx.font = `italic ${greetingFontSize}px ${fontFamily}`;
ctx.fillText(greetingText, canvas.width / 2, greetingY);
ctx.font = `bold ${locationFontSize}px ${fontFamily}`;
ctx.fillText(locationText.toUpperCase(), canvas.width / 2, locationY);
} else if (locationText) { // Only location text
const locationFontSize = Math.max(12, bottomTextSectionHeight * 0.5); // Use 50% of total height, min 12px
ctx.font = `bold ${locationFontSize}px ${fontFamily}`;
ctx.fillText(locationText.toUpperCase(), canvas.width / 2, currentY + bottomTextSectionHeight / 2);
} else if (greetingText) { // Only greeting text
const greetingFontSize = Math.max(10, bottomTextSectionHeight * 0.5); // Use 50% of total height, min 10px
ctx.font = `italic ${greetingFontSize}px ${fontFamily}`;
ctx.fillText(greetingText, canvas.width / 2, currentY + bottomTextSectionHeight / 2);
}
// currentY += bottomTextSectionHeight; // Not strictly needed as stamp is positioned independently
}
// 7. Draw Stamp Graphic (Optional)
if (displayStamp === 1) {
const stampSizeRatio = 0.10; // Stamp size relative to shorter_canvas_dimension
const stampSize = Math.max(30, Math.min(canvas.width, canvas.height) * stampSizeRatio); // Min size 30px
const stampMarginFromEdge = outerPaddingPx * 0.6; // How far from top-right edges
const stampX = canvas.width - stampSize - stampMarginFromEdge;
const stampY = stampMarginFromEdge;
ctx.strokeStyle = stampDetailsColor;
const stampBorderWidth = Math.max(1, stampSize * 0.05); // Border width relative to stamp size
ctx.lineWidth = stampBorderWidth;
ctx.strokeRect(stampX, stampY, stampSize, stampSize);
// Simple decorative "X" lines inside stamp (like a cancellation mark)
const innerLineMargin = stampSize * 0.2; // Margin for inner lines
ctx.beginPath();
ctx.moveTo(stampX + innerLineMargin, stampY + innerLineMargin);
ctx.lineTo(stampX + stampSize - innerLineMargin, stampY + stampSize - innerLineMargin);
ctx.moveTo(stampX + stampSize - innerLineMargin, stampY + innerLineMargin);
ctx.lineTo(stampX + innerLineMargin, stampY + stampSize - innerLineMargin);
ctx.lineWidth = Math.max(1, stampBorderWidth * 0.7); // Slightly thinner lines inside
ctx.stroke();
}
return canvas;
}
Apply Changes