Please bookmark this page to avoid losing your image tool!

Image Secret Society Membership Card 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.
function processImage(
    originalImg,
    memberName = "Alex Doe",
    memberId = `ID-${Math.random().toString(16).slice(2, 10).toUpperCase()}`,
    joinDate = (() => {
        const d = new Date();
        return `${(d.getMonth() + 1).toString().padStart(2, '0')}/${d.getDate().toString().padStart(2, '0')}/${d.getFullYear()}`;
    })(),
    societyName = "The Ancient Order of Coders",
    cardBackgroundColor = "#2c3e50", // Dark Slate Blue
    textColor = "#ecf0f1",         // Clouds (Light Grayish Blue)
    accentColor = "#f1c40f",       // Sunflower (Yellow/Gold)
    statusActiveColor = "#2ecc71", // Emerald Green
    symbolPupilColor = "#111111"   // Very Dark Grey/Almost Black
) {

    // Helper function to draw the society symbol
    function drawSocietySymbol(ctx, x, y, size, triangleColor, irisColor, pupilColor) {
        const h = size * (Math.sqrt(3) / 2); // Height of equilateral triangle

        // Triangle
        ctx.beginPath();
        ctx.moveTo(x + size / 2, y);        // Top point
        ctx.lineTo(x + size, y + h);        // Bottom right
        ctx.lineTo(x, y + h);               // Bottom left
        ctx.closePath();
        ctx.strokeStyle = triangleColor;
        ctx.lineWidth = Math.max(1, Math.floor(size / 18)) + 1; // Proportional line width
        ctx.stroke();

        // Iris (circle)
        const eyeCenterX = x + size / 2;
        const eyeCenterY = y + h * 0.57; // Adjusted for visual centering within triangle
        const irisRadius = size / 3.8;   
        
        ctx.beginPath();
        ctx.arc(eyeCenterX, eyeCenterY, irisRadius, 0, 2 * Math.PI, false);
        ctx.fillStyle = irisColor;
        ctx.fill();

        // Pupil (smaller circle)
        const pupilRadius = irisRadius / 2.2;
        ctx.beginPath();
        ctx.arc(eyeCenterX, eyeCenterY, pupilRadius, 0, 2 * Math.PI, false);
        ctx.fillStyle = pupilColor;
        ctx.fill();
    }

    const cardWidth = 600;
    const cardHeight = 375;

    const canvas = document.createElement('canvas');
    canvas.width = cardWidth;
    canvas.height = cardHeight;
    const ctx = canvas.getContext('2d');

    // 1. Draw Background
    ctx.fillStyle = cardBackgroundColor;
    ctx.fillRect(0, 0, cardWidth, cardHeight);

    // 2. Draw Top Banner with Society Name
    const bannerHeight = 60;
    ctx.fillStyle = accentColor;
    ctx.fillRect(0, 0, cardWidth, bannerHeight);

    // Calculate dynamic font size for banner title
    const bannerFontSize = Math.floor(bannerHeight * 0.45);
    ctx.font = `bold ${bannerFontSize}px 'Georgia', serif`;
    ctx.fillStyle = cardBackgroundColor; // Text color on banner (contrast)
    ctx.textAlign = "center";
    // Adjust vertical position for better centering of text in banner
    const textMetrics = ctx.measureText(societyName); // Not available in all environments for height, but good for width
    // A common heuristic for y-position in canvas text:
    ctx.fillText(societyName, cardWidth / 2, bannerHeight / 2 + bannerFontSize / 3.5);


    // 3. Draw Profile Picture
    const picMargin = 25; // Margin around the picture container
    const picContainerX = picMargin;
    const picContainerY = bannerHeight + picMargin;
    const picContainerWidth = 130;
    const picContainerHeight = 130;

    // Calculate dimensions to fit image within container while maintaining aspect ratio
    let newImgWidth, newImgHeight, imgDrawX, imgDrawY;
    
    // Ensure originalImg has dimensions, otherwise gracefully handle (or draw placeholder)
    const imgNaturalWidth = originalImg.naturalWidth || picContainerWidth; // Fallback if not loaded
    const imgNaturalHeight = originalImg.naturalHeight || picContainerHeight; // Fallback if not loaded

    const imgAspectRatio = imgNaturalWidth / imgNaturalHeight;
    const containerAspectRatio = picContainerWidth / picContainerHeight;

    if (imgAspectRatio > containerAspectRatio) { // Image is wider than container aspect ratio
        newImgWidth = picContainerWidth;
        newImgHeight = newImgWidth / imgAspectRatio;
    } else { // Image is taller or same aspect ratio as container
        newImgHeight = picContainerHeight;
        newImgWidth = newImgHeight * imgAspectRatio;
    }

    imgDrawX = picContainerX + (picContainerWidth - newImgWidth) / 2; // Center horizontally
    imgDrawY = picContainerY + (picContainerHeight - newImgHeight) / 2; // Center vertically
    
    try {
        ctx.drawImage(originalImg, imgDrawX, imgDrawY, newImgWidth, newImgHeight);
    } catch (e) {
        console.error("Error drawing image:", e);
        // Optionally draw a placeholder if image fails
        ctx.fillStyle = "#555";
        ctx.fillRect(picContainerX, picContainerY, picContainerWidth, picContainerHeight);
        ctx.fillStyle = textColor;
        ctx.textAlign = "center";
        ctx.fillText("No Image", picContainerX + picContainerWidth/2, picContainerY + picContainerHeight/2);
    }


    // Border for pic container
    ctx.strokeStyle = accentColor;
    ctx.lineWidth = 3;
    ctx.strokeRect(picContainerX, picContainerY, picContainerWidth, picContainerHeight);

    // 4. Draw Member Details
    const detailsStartX = picContainerX + picContainerWidth + 25; // X start for details text block
    let currentTextY = picContainerY + 5; // Initial Y for text block, align near top of picture

    ctx.textAlign = "left"; // Reset text align

    // "MEMBERSHIP CARD" title under the banner, above details
    ctx.font = "italic 20px 'Georgia', serif";
    ctx.fillStyle = textColor;
    ctx.fillText("MEMBERSHIP CARD", detailsStartX, currentTextY);
    currentTextY += 30; // Space after title

    // Member info properties
    const labelFont = "15px 'Arial', sans-serif";
    const valueFont = "bold 15px 'Arial', sans-serif";
    const labelValueHorizontalOffset = 110; // X-offset from label start to value start
    const lineSpacing = 26; // Vertical space between lines of details

    // Name
    ctx.font = labelFont;
    ctx.fillStyle = textColor; // Ensure text color is set for labels
    ctx.fillText("Name:", detailsStartX, currentTextY);
    ctx.font = valueFont;
    ctx.fillText(memberName, detailsStartX + labelValueHorizontalOffset, currentTextY);
    currentTextY += lineSpacing;

    // ID
    ctx.font = labelFont;
    ctx.fillText("ID:", detailsStartX, currentTextY);
    ctx.font = valueFont;
    ctx.fillText(memberId, detailsStartX + labelValueHorizontalOffset, currentTextY);
    currentTextY += lineSpacing;

    // Join Date
    ctx.font = labelFont;
    ctx.fillText("Member Since:", detailsStartX, currentTextY);
    ctx.font = valueFont;
    ctx.fillText(joinDate, detailsStartX + labelValueHorizontalOffset, currentTextY);
    currentTextY += lineSpacing;
    
    // Status
    ctx.font = labelFont;
    ctx.fillText("Status:", detailsStartX, currentTextY);
    ctx.font = valueFont;
    ctx.fillStyle = statusActiveColor; // Special color for status value
    ctx.fillText("ACTIVE", detailsStartX + labelValueHorizontalOffset, currentTextY);
    // Reset fillStyle for other text if any more details were to be added
    ctx.fillStyle = textColor; 

    // 5. Draw Society Symbol (Logo)
    const symbolSize = 55; // Base size for the symbol (e.g., width of the triangle)
    const symbolMarginFromEdge = 0.05 * cardWidth; // Margin from card edges

    const symbolX = cardWidth - symbolSize - symbolMarginFromEdge;
    // Calculate symbol's drawn height for precise vertical positioning from bottom
    const symbolEffectiveHeight = symbolSize * (Math.sqrt(3) / 2); // Height of equilateral triangle part
    const symbolY = cardHeight - symbolEffectiveHeight - (symbolMarginFromEdge * 0.8); // Position from bottom

    drawSocietySymbol(ctx, symbolX, symbolY, symbolSize, accentColor, accentColor, symbolPupilColor);

    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 Secret Society Membership Card Creator is an online tool that allows users to create personalized membership cards featuring a unique design. Users can input their name, member ID, join date, and select the society’s name, while the tool generates a visually appealing card complete with a profile picture and society symbol. This tool is useful for organizations, clubs, or communities that want to provide their members with customized cards for identification or promotional purposes.

Leave a Reply

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