Please bookmark this page to avoid losing your image tool!

Image Business 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,
    name = "John Doe",
    title = "Software Engineer",
    companyName = "Tech Solutions Inc.",
    phoneNumber = "+1 (555) 123-4567",
    email = "john.doe@example.com",
    website = "www.example.com",
    address = "123 Main St\nCity, State 12345",
    cardWidth = 350,
    cardHeight = 200,
    backgroundColor = "#FFFFFF",
    textColor = "#000000",
    fontFamily = "Arial",
    nameFontSize = 20,
    titleFontSize = 14,
    companyFontSize = 12,
    contactFontSize = 10,
    logoSize = 25, // Percentage of cardHeight for logo's initial target height
    logoPosition = "left", // "left", "right", "topCenter"
    padding = 15, // General padding from card edge to content area
    itemSpacing = 8 // Spacing between major items (logo-text, name-title, etc.)
) {
    const canvas = document.createElement('canvas');
    canvas.width = cardWidth;
    canvas.height = cardHeight;
    const ctx = canvas.getContext('2d');

    // Background
    ctx.fillStyle = backgroundColor;
    ctx.fillRect(0, 0, cardWidth, cardHeight);

    // Content area (after outer padding)
    const actualPadding = padding;
    const availableContentWidth = cardWidth - 2 * actualPadding;
    const availableContentHeight = cardHeight - 2 * actualPadding;

    let drawLogoWidth = 0;
    let drawLogoHeight = 0;
    // Check if originalImg is a valid, loaded image
    const hasLogo = originalImg && 
                    typeof originalImg.width === 'number' && originalImg.width > 0 &&
                    typeof originalImg.height === 'number' && originalImg.height > 0 &&
                    originalImg.complete; // 'complete' checks if image is fully loaded

    if (hasLogo) {
        // Initial logo dimensions based on logoSize (as % of cardHeight) and image aspect ratio
        let targetLogoHeight = (logoSize / 100) * cardHeight;
        let targetLogoWidth = targetLogoHeight * (originalImg.width / originalImg.height);

        // Define maximum allowed dimensions for the logo based on its position and available space
        let maxAllowedLogoWidth, maxAllowedLogoHeight;

        if (logoPosition === "left" || logoPosition === "right") {
            // Logo on the side: can take up to 50% of horizontal content space, full vertical content height
            maxAllowedLogoWidth = (availableContentWidth - itemSpacing) * 0.5; 
            maxAllowedLogoHeight = availableContentHeight;
        } else { // logoPosition === "topCenter"
            // Logo on top: can take full horizontal content width, up to 40% of vertical content space
            maxAllowedLogoWidth = availableContentWidth;
            maxAllowedLogoHeight = (availableContentHeight - itemSpacing) * 0.4;
        }
        
        // Scale to fit max width constraint
        if (targetLogoWidth > maxAllowedLogoWidth) {
            const scale = maxAllowedLogoWidth / targetLogoWidth;
            targetLogoWidth *= scale;
            targetLogoHeight *= scale;
        }
        // Scale to fit max height constraint (applied after width scaling)
        if (targetLogoHeight > maxAllowedLogoHeight) {
            const scale = maxAllowedLogoHeight / targetLogoHeight;
            targetLogoHeight *= scale;
            targetLogoWidth *= scale;
        }
        drawLogoWidth = targetLogoWidth;
        drawLogoHeight = targetLogoHeight;
    }

    // Calculate effective space used by logo (including itemSpacing if logo exists)
    const logoSpaceX = (hasLogo && (logoPosition === "left" || logoPosition === "right")) ? (drawLogoWidth + itemSpacing) : 0;
    const logoSpaceY = (hasLogo && logoPosition === "topCenter") ? (drawLogoHeight + itemSpacing) : 0;

    // Define text block coordinates and dimensions
    let textBlockX, textBlockY, textBlockWidth, textBlockHeight;
    let logoActualX = 0, logoActualY = 0; // Coordinates where logo will be drawn

    if (logoPosition === "left") {
        if (hasLogo) {
            logoActualX = actualPadding;
            logoActualY = actualPadding + (availableContentHeight - drawLogoHeight) / 2; // Vertically center logo
        }
        textBlockX = actualPadding + logoSpaceX;
        textBlockY = actualPadding;
        textBlockWidth = availableContentWidth - logoSpaceX;
        textBlockHeight = availableContentHeight;
    } else if (logoPosition === "right") {
        if (hasLogo) {
            logoActualX = cardWidth - actualPadding - drawLogoWidth;
            logoActualY = actualPadding + (availableContentHeight - drawLogoHeight) / 2; // Vertically center logo
        }
        textBlockX = actualPadding;
        textBlockY = actualPadding;
        textBlockWidth = availableContentWidth - logoSpaceX;
        textBlockHeight = availableContentHeight;
    } else { // topCenter
        if (hasLogo) {
            logoActualX = actualPadding + (availableContentWidth - drawLogoWidth) / 2; // Horizontally center logo
            logoActualY = actualPadding;
        }
        textBlockX = actualPadding;
        textBlockY = actualPadding + logoSpaceY;
        textBlockWidth = availableContentWidth;
        textBlockHeight = availableContentHeight - logoSpaceY;
    }

    // Draw Logo
    if (hasLogo && drawLogoWidth > 0 && drawLogoHeight > 0) {
        ctx.drawImage(originalImg, logoActualX, logoActualY, drawLogoWidth, drawLogoHeight);
    }

    // Draw Text Content
    ctx.fillStyle = textColor;
    ctx.textBaseline = 'top'; // Y coordinate will be the top of the text
    let currentY = textBlockY; // Starting Y for the text block
    const contactLineDetailSpacing = 2; // Small vertical gap between lines of contact info

    // Name
    if (name && name.trim() !== "") {
        if (currentY + nameFontSize > textBlockY + textBlockHeight) return canvas; // Stop if no vertical space
        ctx.font = `bold ${nameFontSize}px ${fontFamily}`;
        ctx.fillText(name, textBlockX, currentY, textBlockWidth); // textBlockWidth acts as maxWidth for fillText
        currentY += nameFontSize + itemSpacing;
    }

    // Title
    if (title && title.trim() !== "") {
        if (currentY + titleFontSize > textBlockY + textBlockHeight) return canvas;
        ctx.font = `${titleFontSize}px ${fontFamily}`;
        ctx.fillText(title, textBlockX, currentY, textBlockWidth);
        currentY += titleFontSize + itemSpacing;
    }

    // Company Name
    if (companyName && companyName.trim() !== "") {
        if (currentY + companyFontSize > textBlockY + textBlockHeight) return canvas;
        ctx.font = `italic ${companyFontSize}px ${fontFamily}`;
        ctx.fillText(companyName, textBlockX, currentY, textBlockWidth);
        currentY += companyFontSize + itemSpacing;
    }
    
    // Contact Info
    ctx.font = `${contactFontSize}px ${fontFamily}`;
    const contactItemLineHeight = contactFontSize + contactLineDetailSpacing;

    if (phoneNumber && phoneNumber.trim() !== "") {
        if (currentY + contactFontSize > textBlockY + textBlockHeight) return canvas;
        ctx.fillText("P: " + phoneNumber, textBlockX, currentY, textBlockWidth);
        currentY += contactItemLineHeight;
    }

    if (email && email.trim() !== "") {
        if (currentY + contactFontSize > textBlockY + textBlockHeight) return canvas;
        ctx.fillText("E: " + email, textBlockX, currentY, textBlockWidth);
        currentY += contactItemLineHeight;
    }

    if (website && website.trim() !== "") {
        if (currentY + contactFontSize > textBlockY + textBlockHeight) return canvas;
        ctx.fillText("W: " + website, textBlockX, currentY, textBlockWidth);
        currentY += contactItemLineHeight;
    }

    if (address && address.trim() !== "") {
        // Add a small gap before the address block if other contact info was present
        if ((phoneNumber && phoneNumber.trim() !== "") || (email && email.trim() !== "") || (website && website.trim() !== "")) {
             currentY += contactLineDetailSpacing; // Additional small gap
        }
       
        const addressLines = address.split('\n');
        for (const line of addressLines) {
            if (currentY + contactFontSize > textBlockY + textBlockHeight) break; 
            ctx.fillText(line, textBlockX, currentY, textBlockWidth);
            currentY += contactItemLineHeight;
        }
    }

    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 Business Card Creator is a versatile tool that allows users to design custom business cards by incorporating personal and professional details such as name, job title, company name, phone number, email, website, and address. Users can customize the dimensions, colors, font styles, and layout of the card, including the ability to add and position a logo. This tool is ideal for professionals looking to create personalized business cards for networking events, conferences, or personal branding, offering an easy and efficient way to produce high-quality card designs.

Leave a Reply

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