Please bookmark this page to avoid losing your image tool!

Image Recipe Add Tool

(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, title = "Classic Pancakes", ingredients = "1 1/2 cups all-purpose flour\n3 1/2 teaspoons baking powder\n1 teaspoon salt\n1 tablespoon white sugar\n1 1/4 cups milk\n1 egg\n3 tablespoons butter, melted", instructions = "1. In a large bowl, sift together the flour, baking powder, salt and sugar.\n2. Make a well in the center and pour in the milk, egg and melted butter; mix until smooth.\n3. Heat a lightly oiled griddle or frying pan over medium high heat.\n4. Pour or scoop the batter onto the griddle, using approximately 1/4 cup for each pancake.\n5. Brown on both sides and serve hot.", fontFamily = "Georgia, serif", fontSize = 16, textColor = "#FFFFFF", backgroundColor = "rgba(0, 0, 0, 0.6)", padding = 25, position = "topLeft") {

    // 1. Create canvas and draw the original image
    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d');
    canvas.width = originalImg.naturalWidth;
    canvas.height = originalImg.naturalHeight;
    ctx.drawImage(originalImg, 0, 0);

    // 2. Define text styles and parse multi-line text
    const titleSize = Math.round(fontSize * 1.5);
    const headerSize = Math.round(fontSize * 1.1);
    const bodySize = fontSize;
    const lineSpacing = fontSize * 0.5;

    const ingredientLines = ingredients.split('\n').filter(line => line.trim() !== '');
    const instructionLines = instructions.split('\n').filter(line => line.trim() !== '');
    const ingredientsHeader = "INGREDIENTS";
    const instructionsHeader = "INSTRUCTIONS";

    // 3. Measure the required dimensions for the recipe box without drawing
    let contentWidth = 0;
    let contentHeightTracker = padding; // Start with top padding

    // Measure Title
    ctx.font = `bold ${titleSize}px ${fontFamily}`;
    contentWidth = Math.max(contentWidth, ctx.measureText(title).width);
    contentHeightTracker += titleSize + lineSpacing * 2;

    // Measure Ingredients Header
    ctx.font = `bold ${headerSize}px ${fontFamily}`;
    contentWidth = Math.max(contentWidth, ctx.measureText(ingredientsHeader).width);
    contentHeightTracker += headerSize + lineSpacing;

    // Measure Ingredient Lines
    ctx.font = `${bodySize}px ${fontFamily}`;
    ingredientLines.forEach(line => {
        contentWidth = Math.max(contentWidth, ctx.measureText(line).width);
        contentHeightTracker += bodySize + lineSpacing;
    });

    contentHeightTracker += lineSpacing; // Extra space between sections

    // Measure Instructions Header
    ctx.font = `bold ${headerSize}px ${fontFamily}`;
    contentWidth = Math.max(contentWidth, ctx.measureText(instructionsHeader).width);
    contentHeightTracker += headerSize + lineSpacing;

    // Measure Instruction Lines
    ctx.font = `${bodySize}px ${fontFamily}`;
    instructionLines.forEach(line => {
        contentWidth = Math.max(contentWidth, ctx.measureText(line).width);
        contentHeightTracker += bodySize + lineSpacing;
    });

    // Final box dimensions
    const totalBoxWidth = contentWidth + padding * 2;
    // contentHeightTracker includes all text heights and spacings. The last line added an extra lineSpacing.
    // We replace that last spacing with the bottom padding.
    const totalBoxHeight = contentHeightTracker - lineSpacing + padding;

    // 4. Calculate the top-left (x, y) coordinates for the box based on position
    let boxX, boxY;
    const margin = Number(padding); // Use padding as margin from edge

    switch (position) {
        case 'topRight':
            boxX = canvas.width - totalBoxWidth - margin;
            boxY = margin;
            break;
        case 'bottomLeft':
            boxX = margin;
            boxY = canvas.height - totalBoxHeight - margin;
            break;
        case 'bottomRight':
            boxX = canvas.width - totalBoxWidth - margin;
            boxY = canvas.height - totalBoxHeight - margin;
            break;
        case 'center':
            boxX = (canvas.width - totalBoxWidth) / 2;
            boxY = (canvas.height - totalBoxHeight) / 2;
            break;
        case 'topLeft':
        default:
            boxX = margin;
            boxY = margin;
            break;
    }
    
    // Clamp box position to be within the canvas
    boxX = Math.max(0, boxX);
    boxY = Math.max(0, boxY);

    // 5. Draw the background box
    ctx.fillStyle = backgroundColor;
    ctx.fillRect(boxX, boxY, totalBoxWidth, Math.min(totalBoxHeight, canvas.height - boxY));

    // 6. Draw the text
    ctx.fillStyle = textColor;
    ctx.textBaseline = 'top';
    let currentY = boxY + padding;
    const textX = boxX + padding;

    // Draw Title
    ctx.font = `bold ${titleSize}px ${fontFamily}`;
    ctx.fillText(title, textX, currentY);
    currentY += titleSize + lineSpacing * 2;

    // Draw Ingredients
    ctx.font = `bold ${headerSize}px ${fontFamily}`;
    ctx.fillText(ingredientsHeader, textX, currentY);
    currentY += headerSize + lineSpacing;
    
    ctx.font = `${bodySize}px ${fontFamily}`;
    ingredientLines.forEach(line => {
        ctx.fillText(line, textX, currentY);
        currentY += bodySize + lineSpacing;
    });
    
    currentY += lineSpacing; // Extra space

    // Draw Instructions
    ctx.font = `bold ${headerSize}px ${fontFamily}`;
    ctx.fillText(instructionsHeader, textX, currentY);
    currentY += headerSize + lineSpacing;
    
    ctx.font = `${bodySize}px ${fontFamily}`;
    instructionLines.forEach(line => {
        ctx.fillText(line, textX, currentY);
        currentY += bodySize + lineSpacing;
    });

    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 Add Tool allows users to create visually appealing recipe images by adding text overlays to an original image. Users can specify a title, list of ingredients, and detailed instructions for a recipe that will be displayed on top of their selected image. This tool is ideal for food bloggers, cooking enthusiasts, and anyone looking to visually share recipes on social media or in digital cookbooks. It offers customization options for font style, size, text color, and background appearance to ensure the recipe information is both legible and aesthetically pleasing.

Leave a Reply

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