Please bookmark this page to avoid losing your image tool!

Image Decoration 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.
/**
 * Decorates an image by adding a frame, text, and a color overlay.
 * This function is asynchronous to handle dynamic font loading from Google Fonts.
 *
 * @param {Image} originalImg The original Image object to decorate.
 * @param {number} frameWidth The width of the frame in pixels. Set to 0 for no frame.
 * @param {string} frameColor The color of the frame (e.g., 'black', '#FF0000').
 * @param {string} text The text to overlay on the image. Set to "" for no text.
 * @param {number} fontSize The font size of the text in pixels.
 * @param {string} fontFamily The font family for the text. Can be a web-safe font or a Google Font name (e.g., 'Anton', 'Roboto').
 * @param {string} textColor The fill color of the text.
 * @param {number} textOutlineWidth The width of the text's outline in pixels.
 * @param {string} textOutlineColor The color of the text's outline.
 * @param {string} textPosition The vertical position of the text ('top', 'center', 'bottom').
 * @param {string} overlayColor A semi-transparent color to overlay on the image (e.g., 'rgba(255, 0, 0, 0.2)'). Use a fully transparent color for no overlay.
 * @param {string} overlayBlendMode The canvas composite operation for the overlay (e.g., 'multiply', 'screen', 'overlay', 'source-over').
 * @returns {Promise<HTMLCanvasElement>} A promise that resolves with the decorated canvas element.
 */
async function processImage(
    originalImg,
    frameWidth = 10,
    frameColor = "black",
    text = "DECORATOR",
    fontSize = 48,
    fontFamily = "Anton",
    textColor = "white",
    textOutlineWidth = 3,
    textOutlineColor = "black",
    textPosition = "bottom",
    overlayColor = "rgba(0,0,0,0)",
    overlayBlendMode = "source-over"
) {

    // Helper function to dynamically load Google Fonts
    const loadFont = async (fontName) => {
        const webSafeFonts = [
            'arial', 'verdana', 'helvetica', 'tahoma', 'trebuchet ms', 
            'times new roman', 'georgia', 'garamond', 'courier new', 
            'brush script mt', 'impact', 'comic sans ms'
        ];
        
        const sanitizedFontName = fontName.split(',')[0].trim().replace(/['"]/g, '');
        if (webSafeFonts.includes(sanitizedFontName.toLowerCase())) {
            return; // It's a web-safe font, no need to load
        }

        // Load Google Font
        const fontId = `google-font-${sanitizedFontName.replace(/ /g, '-')}`;
        if (!document.getElementById(fontId)) {
            const link = document.createElement('link');
            link.id = fontId;
            link.rel = 'stylesheet';
            link.href = `https://fonts.googleapis.com/css2?family=${sanitizedFontName.replace(/ /g, '+')}&display=swap`;
            document.head.appendChild(link);
            try {
                await document.fonts.load(`12px "${sanitizedFontName}"`);
            } catch (e) {
                console.error(`Could not load Google Font "${sanitizedFontName}". A fallback font will be used.`, e);
            }
        }
    };

    // Load the font if text is provided
    if (text && text.trim() !== '') {
        await loadFont(fontFamily);
    }
    
    // --- Canvas Setup ---
    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d');

    canvas.width = originalImg.width + 2 * frameWidth;
    canvas.height = originalImg.height + 2 * frameWidth;

    // --- Drawing Operations ---

    // 1. Draw Frame
    if (frameWidth > 0) {
        ctx.fillStyle = frameColor;
        ctx.fillRect(0, 0, canvas.width, canvas.height);
    }

    // 2. Draw Original Image
    ctx.drawImage(originalImg, frameWidth, frameWidth, originalImg.width, originalImg.height);

    // 3. Draw Color Overlay
    // We check for alpha value to see if the color is transparent
    const alpha = parseFloat(overlayColor.split(',')[3] || '1');
    if (alpha > 0) {
       ctx.globalCompositeOperation = overlayBlendMode;
       ctx.fillStyle = overlayColor;
       ctx.fillRect(frameWidth, frameWidth, originalImg.width, originalImg.height);
       ctx.globalCompositeOperation = 'source-over'; // Reset blend mode
    }

    // 4. Draw Text
    if (text && text.trim() !== '') {
        const sanitizedFontName = fontFamily.split(',')[0].trim().replace(/['"]/g, '');
        const fullFontString = `${fontSize}px "${sanitizedFontName}", sans-serif`;

        // Wait for fonts to be ready before drawing
        await document.fonts.ready;
        
        ctx.font = fullFontString;
        ctx.fillStyle = textColor;
        ctx.strokeStyle = textOutlineColor;
        ctx.lineWidth = textOutlineWidth;
        ctx.textAlign = 'center';

        const x = canvas.width / 2;
        const maxWidth = originalImg.width > 20 ? originalImg.width - 20 : originalImg.width;

        // Auto-wrap text logic
        const words = text.split(' ');
        let line = '';
        const lines = [];
        for(const word of words) {
            const testLine = line + word + ' ';
            const metrics = ctx.measureText(testLine);
            if (metrics.width > maxWidth && line.length > 0) {
                lines.push(line.trim());
                line = word + ' ';
            } else {
                line = testLine;
            }
        }
        lines.push(line.trim());

        const lineHeight = fontSize * 1.2;
        let startY;

        // Calculate starting Y position based on desired alignment and number of lines
        switch(textPosition.toLowerCase()) {
            case 'top':
                ctx.textBaseline = 'top';
                startY = frameWidth + (fontSize * 0.2);
                break;
            case 'center':
                ctx.textBaseline = 'top';
                const totalTextHeight = (lines.length - 1) * lineHeight + fontSize;
                startY = (canvas.height - totalTextHeight) / 2;
                break;
            case 'bottom':
            default:
                ctx.textBaseline = 'bottom';
                startY = canvas.height - frameWidth - (fontSize * 0.2) - (lines.length - 1) * lineHeight;
                break;
        }

        // Draw each line of text
        for (let i = 0; i < lines.length; i++) {
             const lineY = (ctx.textBaseline === 'top') ? startY + (i * lineHeight) : startY + (i * lineHeight);
             if (textOutlineWidth > 0) {
                 ctx.strokeText(lines[i], x, lineY);
             }
             ctx.fillText(lines[i], x, lineY);
        }
    }

    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 Decoration Tool allows users to enhance images by adding decorative elements such as frames, text overlays, and color overlays. This tool can be used for various purposes, including customizing images for social media posts, creating personalized gifts, or adding artistic flair to photos for presentations and blogs. Users can specify frame dimensions, choose colors, and select fonts to create unique designs that match their specific aesthetic needs.

Leave a Reply

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