Please bookmark this page to avoid losing your image tool!

Image Marriage Certificate Template Creator

(Free & Supports Bulk Upload)

Drag & drop your images here or

The result will appear here...
You can edit the below JavaScript code to customize the image tool.
async function processImage(
    originalImg,
    brideName = "Jane Doe",
    groomName = "John Doe",
    marriageDate = "January 1, 2024",
    location = "City Hall, Anytown",
    officiantName = "Rev. Officiant Name",
    officiantTitle = "Officiant",
    witness1Name = "Witness One",
    witness2Name = "Witness Two"
) {

    // Helper function to load a custom font
    async function loadAndApplyCustomFont(fontFamily, fontUrl) {
        if (document.fonts.check(`12px "${fontFamily}"`)) {
            // Font is likely already available or has been loaded.
            return;
        }
        const newFont = new FontFace(fontFamily, `url(${fontUrl}) format('woff2')`);
        try {
            await newFont.load();
            document.fonts.add(newFont);
            // console.log(`${fontFamily} font loaded and added successfully.`);
        } catch (err) {
            console.error(`Failed to load font ${fontFamily} from ${fontUrl}:`, err);
            // Browser will use fallback font specified in ctx.font (e.g., 'cursive', 'serif')
        }
    }

    // Helper function to get day suffix (1st, 2nd, 3rd, th)
    function getDaySuffix(d) {
        if (d > 3 && d < 21) return 'th';
        switch (d % 10) {
            case 1: return "st";
            case 2: return "nd";
            case 3: return "rd";
            default: return "th";
        }
    }

    // Helper function to draw a border
    function drawCertificateBorder(ctx, W, H) {
        const padding = 20; // Outer padding for the border
        ctx.strokeStyle = '#B08D57'; // A gold-ish brown for the border lines

        // Outer border line
        const outerThickness = 3; // Thickness of the main border line
        ctx.lineWidth = outerThickness;
        ctx.strokeRect(padding, padding, W - 2 * padding, H - 2 * padding);

        // Inner, thinner border line
        const gapBetweenLines = 4; // Gap between outer and inner border lines
        const innerPadding = padding + outerThickness + gapBetweenLines;
        const innerThickness = 1.5; // Thickness of the inner decorative line
        ctx.lineWidth = innerThickness;
        ctx.strokeRect(innerPadding, innerPadding, W - 2 * innerPadding, H - 2 * innerPadding);
    }

    // Load the "Great Vibes" font for decorative script text
    // Using a common CDN link for Google Fonts' "Great Vibes"
    await loadAndApplyCustomFont('Great Vibes', 'https://fonts.gstatic.com/s/greatvibes/v18/RWmMoKWR9v4hfMFldRvRIieM.woff2');

    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d');

    const W = 1000; // Standard canvas width for the certificate
    const H = 700;  // Standard canvas height
    canvas.width = W;
    canvas.height = H;

    // Fill background
    ctx.fillStyle = '#FFF8E1'; // A light cream, parchment-like color
    ctx.fillRect(0, 0, W, H);

    // Draw the decorative border
    drawCertificateBorder(ctx, W, H);

    // --- Content Drawing Starts Here ---
    ctx.fillStyle = '#4A2300'; // Dark Brown, for good contrast and classic look
    ctx.textAlign = 'center';   // Most text will be centered

    let currentY = 30; // Initial top margin from the border padding area

    // Optional Image (e.g., a seal, emblem, or small photo)
    const imgMaxDesiredHeight = 60; // Max height for the image
    if (originalImg && originalImg.complete && originalImg.naturalWidth > 0 && originalImg.naturalHeight > 0) {
        try {
            const aspectRatio = originalImg.naturalWidth / originalImg.naturalHeight;
            let imgH = imgMaxDesiredHeight;
            let imgW = imgH * aspectRatio;
            
            const maxImgWidth = W * 0.5; // Image should not exceed half canvas width
            if (imgW > maxImgWidth) {
                imgW = maxImgWidth;
                imgH = imgW / aspectRatio;
            }

            const imgX = (W - imgW) / 2; // Centered horizontally
            ctx.drawImage(originalImg, imgX, currentY, imgW, imgH);
            currentY += imgH + 15; // Add image height and some padding below it
        } catch (e) {
            console.error("Error drawing original image:", e);
            currentY += 15; // Fallback spacing if image fails
        }
    } else {
        currentY += 15; // Spacing if no image is provided or loaded
    }

    // Main Title
    ctx.font = `bold 56px "Great Vibes", cursive`; // Large, decorative font
    ctx.fillText("Certificate of Marriage", W / 2, currentY);
    currentY += 60; // Space after title

    // Introductory phrase
    ctx.font = `20px "Georgia", serif`; // Clear, classic serif font
    ctx.fillText("This Certifies That", W / 2, currentY);
    currentY += 30;

    // Groom's Name
    ctx.font = `38px "Great Vibes", cursive`;
    ctx.fillText(groomName, W / 2, currentY);
    currentY += 35;

    // "and"
    ctx.font = `18px "Georgia", serif`;
    ctx.fillText("and", W / 2, currentY);
    currentY += 30;

    // Bride's Name
    ctx.font = `38px "Great Vibes", cursive`;
    ctx.fillText(brideName, W / 2, currentY);
    currentY += 40;

    // Declaration of union
    ctx.font = `20px "Georgia", serif`;
    ctx.fillText("Were united in Holy Matrimony", W / 2, currentY);
    currentY += 30;

    // Date of marriage
    const dateObj = new Date(marriageDate); // Parse the date string
    const day = dateObj.getDate();
    const monthNames = ["January", "February", "March", "April", "May", "June",
                        "July", "August", "September", "October", "November", "December"];
    const month = monthNames[dateObj.getMonth()];
    const year = dateObj.getFullYear();
    const dateString = `on the ${day}${getDaySuffix(day)} day of ${month}, ${year}`;
    ctx.font = `16px "Georgia", serif`;
    ctx.fillText(dateString, W / 2, currentY);
    currentY += 25;

    // Location of marriage
    ctx.fillText(`at ${location}`, W / 2, currentY);
    currentY += 30;

    // Officiant's details
    ctx.font = `18px "Georgia", serif`;
    ctx.fillText(`By ${officiantName}`, W / 2, currentY);
    currentY += 20;
    ctx.font = `italic 14px "Georgia", serif`;
    ctx.fillText(officiantTitle, W / 2, currentY);
    // Note: currentY is now the baseline of the officiant's title.

    // --- Signature Sections ---
    // These are positioned from the bottom-up relative to canvas height for stable layout
    const sigLineColor = '#6D4C41'; // A slightly muted brown for signature lines
    ctx.strokeStyle = sigLineColor;
    ctx.lineWidth = 1; // Standard line thickness

    const textOffsetY = 20;  // Vertical offset for names below signature lines
    const labelOffsetY = textOffsetY + 15; // Vertical offset for labels (e.g., "Groom")

    // Y positions for signature lines
    const mainSigLineY = H - 100;    // For Groom, Bride, Officiant
    const witnessLineY = mainSigLineY - 80; // For Witnesses
    const witnessHeadingY = witnessLineY - 30; // For "In the presence of witnesses" text

    // "In the presence of witnesses:" text
    ctx.font = `16px "Georgia", serif`;
    ctx.fillStyle = '#4A2300'; // Ensure text color is set
    ctx.fillText("In the presence of witnesses:", W / 2, witnessHeadingY);

    // Witness Signatures
    const witnessSigLineWidth = W / 4.5; // Approx. 222px, adjust as needed
    const witnessNameFont = `14px "Georgia", serif`;
    const witnessLabelFont = `italic 12px "Georgia", serif`;

    const witness1X = W / 2 - witnessSigLineWidth / 2 - 30; // Left witness
    ctx.beginPath();
    ctx.moveTo(witness1X - witnessSigLineWidth / 2, witnessLineY);
    ctx.lineTo(witness1X + witnessSigLineWidth / 2, witnessLineY);
    ctx.stroke();
    ctx.font = witnessNameFont;
    ctx.fillText(witness1Name, witness1X, witnessLineY + textOffsetY);
    ctx.font = witnessLabelFont;
    ctx.fillText("Witness", witness1X, witnessLineY + labelOffsetY);

    const witness2X = W / 2 + witnessSigLineWidth / 2 + 30; // Right witness
    ctx.beginPath();
    ctx.moveTo(witness2X - witnessSigLineWidth / 2, witnessLineY);
    ctx.lineTo(witness2X + witnessSigLineWidth / 2, witnessLineY);
    ctx.stroke();
    ctx.font = witnessNameFont;
    ctx.fillText(witness2Name, witness2X, witnessLineY + textOffsetY);
    ctx.font = witnessLabelFont;
    ctx.fillText("Witness", witness2X, witnessLineY + labelOffsetY);

    // Main Signatures (Groom, Bride, Officiant)
    const mainSigLineWidth = W / 4.5; // Approx. 222px
    const mainNameFont = `14px "Georgia", serif`;
    const mainLabelFont = `italic 12px "Georgia", serif`;
    const spacingBetweenMainSigs = mainSigLineWidth + 60; // Center-to-center spacing

    const groomSigX = W / 2 - spacingBetweenMainSigs;
    ctx.beginPath();
    ctx.moveTo(groomSigX - mainSigLineWidth / 2, mainSigLineY);
    ctx.lineTo(groomSigX + mainSigLineWidth / 2, mainSigLineY);
    ctx.stroke();
    ctx.font = mainNameFont;
    ctx.fillText(groomName, groomSigX, mainSigLineY + textOffsetY);
    ctx.font = mainLabelFont;
    ctx.fillText("Groom", groomSigX, mainSigLineY + labelOffsetY);

    const brideSigX = W / 2;
    ctx.beginPath();
    ctx.moveTo(brideSigX - mainSigLineWidth / 2, mainSigLineY);
    ctx.lineTo(brideSigX + mainSigLineWidth / 2, mainSigLineY);
    ctx.stroke();
    ctx.font = mainNameFont;
    ctx.fillText(brideName, brideSigX, mainSigLineY + textOffsetY);
    ctx.font = mainLabelFont;
    ctx.fillText("Bride", brideSigX, mainSigLineY + labelOffsetY);
    
    const officiantSigX = W / 2 + spacingBetweenMainSigs;
    ctx.beginPath();
    ctx.moveTo(officiantSigX - mainSigLineWidth / 2, mainSigLineY);
    ctx.lineTo(officiantSigX + mainSigLineWidth / 2, mainSigLineY);
    ctx.stroke();
    ctx.font = mainNameFont;
    ctx.fillText(officiantName, officiantSigX, mainSigLineY + textOffsetY);
    ctx.font = mainLabelFont;
    ctx.fillText(officiantTitle, officiantSigX, mainSigLineY + labelOffsetY);

    return canvas;
}

Free Image Tool Creator

Can't find the image tool you're looking for?
Create one based on your own needs now!

Description

The Image Marriage Certificate Template Creator is a versatile online tool that allows users to design customized marriage certificates. By inputting personal details such as the names of the bride and groom, the marriage date, location, and officiant information, users can create visually appealing and professional-looking certificates. This tool is ideal for wedding planners, couples preparing for their marriage, or anyone needing to generate a formal marriage certificate for their records or as part of a wedding celebration.

Leave a Reply

Your email address will not be published. Required fields are marked *