Please bookmark this page to avoid losing your image tool!

Image Recipe Category Organizer

(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, categoryName = 'DESSERTS', recipeTitle = 'Amazing Recipe Title', textColor = '#FFFFFF', backgroundColor = 'rgba(0, 0, 0, 0.5)') {

    /**
     * Dynamically loads necessary Google Fonts using the FontFace API.
     * This avoids polluting the global scope and ensures fonts are ready before drawing.
     */
    async function loadFonts() {
        try {
            const playfairFont = new FontFace(
                'Playfair Display',
                'url(https://fonts.gstatic.com/s/playfairdisplay/v30/nuFvD-vYSZviVYUb_rj3ij__anPXJzDwcbmjWMI.woff2)', {
                    weight: '700'
                }
            );
            const montserratFont = new FontFace(
                'Montserrat',
                'url(https://fonts.gstatic.com/s/montserrat/v25/JTUHjIg1_i6t8kCHKm4532VJOt5-QNFgpCtr6Hw5aXo.woff2)', {
                    weight: '700'
                }
            );

            // Wait for both fonts to be loaded in parallel
            await Promise.all([playfairFont.load(), montserratFont.load()]);

            // Add the fonts to the document's font set, making them available for the canvas
            document.fonts.add(playfairFont);
            document.fonts.add(montserratFont);
        } catch (error) {
            console.error("Font loading failed. Using browser default fonts.", error);
            // The function will gracefully fall back to default fonts if loading fails.
        }
    }

    // Await the font loading process before proceeding
    await loadFonts();

    // 1. Create a canvas and get its 2D rendering context
    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d');

    // 2. Set canvas dimensions to match the original image
    canvas.width = originalImg.naturalWidth;
    canvas.height = originalImg.naturalHeight;

    // 3. Draw the original image onto the canvas to serve as the background
    ctx.drawImage(originalImg, 0, 0, canvas.width, canvas.height);

    // 4. Define and draw the semi-transparent background rectangle for the text
    // This makes the text readable regardless of the background image's complexity.
    const rectWidth = canvas.width * 0.8;
    const rectHeight = canvas.height * 0.35;
    const rectX = (canvas.width - rectWidth) / 2;
    const rectY = (canvas.height - rectHeight) / 2;

    ctx.fillStyle = backgroundColor;
    ctx.fillRect(rectX, rectY, rectWidth, rectHeight);


    // 5. Set up shared text properties
    ctx.fillStyle = textColor;
    ctx.textAlign = 'center';
    ctx.textBaseline = 'middle';


    // 6. Draw the 'Category' text
    const categoryFontSize = Math.max(12, Math.round(canvas.height * 0.035));
    ctx.font = `700 ${categoryFontSize}px Montserrat`;
    // Use letter-spacing for a modern, stylistic look if the browser supports it.
    if ('letterSpacing' in ctx) {
        ctx.letterSpacing = '3px';
    }
    const categoryY = rectY + rectHeight * 0.25;
    ctx.fillText(categoryName.toUpperCase(), canvas.width / 2, categoryY);
    // Reset letter-spacing for subsequent text
    if ('letterSpacing' in ctx) {
        ctx.letterSpacing = '0px';
    }

    // 7. Draw a decorative line between the category and the title
    const lineY = rectY + rectHeight * 0.45;
    const lineWidth = rectWidth * 0.2;
    const lineXStart = (canvas.width - lineWidth) / 2;
    ctx.strokeStyle = textColor;
    ctx.lineWidth = Math.max(1, Math.round(canvas.height * 0.002));
    ctx.beginPath();
    ctx.moveTo(lineXStart, lineY);
    ctx.lineTo(lineXStart + lineWidth, lineY);
    ctx.stroke();

    // 8. Draw the 'Recipe Title'
    let titleFontSize = Math.max(24, Math.round(canvas.height * 0.07));
    ctx.font = `700 ${titleFontSize}px "Playfair Display"`;

    // Dynamically adjust font size to ensure the title fits inside the rectangle
    const maxWidth = rectWidth * 0.9; // 90% of the box width for padding
    let textMetrics = ctx.measureText(recipeTitle);

    while (textMetrics.width > maxWidth && titleFontSize > 12) {
        titleFontSize--;
        ctx.font = `700 ${titleFontSize}px "Playfair Display"`;
        textMetrics = ctx.measureText(recipeTitle);
    }
    const titleY = rectY + rectHeight * 0.7;
    ctx.fillText(recipeTitle, canvas.width / 2, titleY);

    // 9. Return the final canvas element
    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 Recipe Category Organizer is a web-based tool designed to enhance recipe images by adding text overlays that categorize the recipe and title. Users can input an image along with a selected category and recipe title, which the tool then processes to generate a visually appealing image suitable for sharing or use in recipe collections. This tool can be particularly useful for food bloggers, recipe developers, and social media influencers who wish to create attractive visuals for their culinary content. It also incorporates customizable text colors and backgrounds to ensure readability and aesthetic appeal.

Leave a Reply

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