Please bookmark this page to avoid losing your image tool!

Image Language And Code Integrator

(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, codeSnippet = `const greet = (name) => {
  return \`Hello, \${name}!\`;
};

console.log(greet('Developer'));`, language = 'javascript', theme = 'dark', fontSize = 16, position = 'bottomRight', padding = 30) {

    /**
     * Helper function to dynamically load a Google Font.
     * It adds the font's stylesheet to the document head and waits for the font to be ready for use.
     * @param {string} fontFamily The name of the Google Font (e.g., 'Source Code Pro').
     * @returns {Promise<void>} A promise that resolves when the font is loaded and ready.
     */
    const loadGoogleFont = async (fontFamily) => {
        const fontId = `google-font-${fontFamily.replace(/\s/g, '-')}`;
        if (document.getElementById(fontId)) {
            await document.fonts.load(`1em "${fontFamily}"`);
            return;
        }

        return new Promise((resolve, reject) => {
            const link = document.createElement('link');
            link.id = fontId;
            link.rel = 'stylesheet';
            link.href = `https://fonts.googleapis.com/css2?family=${fontFamily.replace(/\s/g, '+')}:wght@400&display=swap`;
            link.onload = () => document.fonts.load(`1em "${fontFamily}"`).then(resolve, reject);
            link.onerror = () => reject(new Error(`Failed to load Google Font: ${fontFamily}`));
            document.head.appendChild(link);
        });
    };

    /**
     * Helper function to draw a rectangle with rounded corners on a canvas.
     * @param {CanvasRenderingContext2D} ctx The canvas rendering context.
     * @param {number} x The top-left x-coordinate.
     * @param {number} y The top-left y-coordinate.
     * @param {number} width The width of the rectangle.
     * @param {number} height The height of the rectangle.
     * @param {number} radius The corner radius.
     */
    const roundRect = (ctx, x, y, width, height, radius) => {
        ctx.beginPath();
        ctx.moveTo(x + radius, y);
        ctx.arcTo(x + width, y, x + width, y + height, radius);
        ctx.arcTo(x + width, y + height, x, y + height, radius);
        ctx.arcTo(x, y + height, x, y, radius);
        ctx.arcTo(x, y, x + width, y, radius);
        ctx.closePath();
    };

    // 1. Setup Canvas
    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d');
    canvas.width = originalImg.naturalWidth;
    canvas.height = originalImg.naturalHeight;

    // 2. Draw Original Image
    ctx.drawImage(originalImg, 0, 0);

    // 3. Load Required Font
    const fontFamily = 'Source Code Pro';
    try {
        await loadGoogleFont(fontFamily);
    } catch (e) {
        console.error(e);
        // Fallback to a web-safe monospace font
        // fontFamily = 'monospace'; // This would require changing the const to let
    }

    // 4. Set Theme Colors
    let bgColor, textColor, headerColor, shadowColor, titleColor;
    if (theme === 'light') {
        bgColor = 'rgba(245, 245, 245, 0.9)';
        textColor = '#333333';
        headerColor = 'rgba(225, 225, 225, 0.9)';
        shadowColor = 'rgba(0, 0, 0, 0.2)';
        titleColor = 'rgba(51, 51, 51, 0.7)';
    } else { // default to 'dark' theme
        bgColor = 'rgba(40, 42, 54, 0.9)';
        textColor = '#f8f8f2';
        headerColor = 'rgba(30, 31, 41, 0.9)';
        shadowColor = 'rgba(0, 0, 0, 0.5)';
        titleColor = 'rgba(248, 248, 242, 0.6)';
    }

    // 5. Calculate Code Block Metrics
    ctx.font = `${fontSize}px "${fontFamily}", monospace`;
    ctx.textBaseline = 'top';
    const lines = codeSnippet.split('\n');
    const lineHeight = fontSize * 1.5;
    const headerHeight = 40;
    const windowButtonRadius = 7;

    let maxWidth = 0;
    lines.forEach(line => {
        const metrics = ctx.measureText(line);
        if (metrics.width > maxWidth) maxWidth = metrics.width;
    });

    const codeBlockWidth = maxWidth + padding * 2;
    const codeBlockHeight = headerHeight + (lines.length * lineHeight) + padding;

    // 6. Calculate Position of the Code Block
    let verticalPos, horizontalPos;
    const pos = position.toLowerCase();

    if (pos.startsWith('top')) verticalPos = 'top';
    else if (pos.startsWith('bottom')) verticalPos = 'bottom';
    else verticalPos = 'center';

    if (pos.endsWith('left')) horizontalPos = 'left';
    else if (pos.endsWith('right')) horizontalPos = 'right';
    else horizontalPos = 'center';

    let x, y;
    const margin = 40; // Margin from canvas edges

    switch (horizontalPos) {
        case 'right': x = canvas.width - codeBlockWidth - margin; break;
        case 'left': x = margin; break;
        default: x = (canvas.width - codeBlockWidth) / 2; break; // center
    }
    switch (verticalPos) {
        case 'bottom': y = canvas.height - codeBlockHeight - margin; break;
        case 'top': y = margin; break;
        default: y = (canvas.height - codeBlockHeight) / 2; break; // center
    }

    // Clamp position to ensure the block is always visible
    x = Math.max(10, Math.min(x, canvas.width - codeBlockWidth - 10));
    y = Math.max(10, Math.min(y, canvas.height - codeBlockHeight - 10));

    const cornerRadius = 8;
    
    // 7. Draw the Code Block UI
    ctx.save();
    ctx.shadowColor = shadowColor;
    ctx.shadowBlur = 30;
    ctx.shadowOffsetY = 10;
    roundRect(ctx, x, y, codeBlockWidth, codeBlockHeight, cornerRadius);
    ctx.fillStyle = bgColor;
    ctx.fill();
    ctx.restore();

    // Draw header area on top
    ctx.fillStyle = headerColor;
    ctx.beginPath();
    ctx.moveTo(x, y + headerHeight);
    ctx.lineTo(x, y + cornerRadius);
    ctx.arcTo(x, y, x + cornerRadius, y, cornerRadius);
    ctx.lineTo(x + codeBlockWidth - cornerRadius, y);
    ctx.arcTo(x + codeBlockWidth, y, x + codeBlockWidth, y + cornerRadius, cornerRadius);
    ctx.lineTo(x + codeBlockWidth, y + headerHeight);
    ctx.closePath();
    ctx.fill();

    // Draw macOS-style window buttons
    const buttonY = y + headerHeight / 2;
    const buttonXStart = x + padding;
    ctx.fillStyle = '#ff5f56';
    ctx.beginPath();
    ctx.arc(buttonXStart, buttonY, windowButtonRadius, 0, Math.PI * 2);
    ctx.fill();
    ctx.fillStyle = '#ffbd2e';
    ctx.beginPath();
    ctx.arc(buttonXStart + windowButtonRadius * 2.5, buttonY, windowButtonRadius, 0, Math.PI * 2);
    ctx.fill();
    ctx.fillStyle = '#27c93f';
    ctx.beginPath();
    ctx.arc(buttonXStart + windowButtonRadius * 5, buttonY, windowButtonRadius, 0, Math.PI * 2);
    ctx.fill();
    
    // Draw language title in the header
    ctx.fillStyle = titleColor;
    ctx.font = `13px "SF Pro Text", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif`;
    ctx.textAlign = 'center';
    ctx.textBaseline = 'middle';
    ctx.fillText(language.toLowerCase(), x + codeBlockWidth / 2, buttonY);

    // 8. Draw the Code Text
    ctx.fillStyle = textColor;
    ctx.font = `${fontSize}px "${fontFamily}", monospace`;
    ctx.textAlign = 'left';
    ctx.textBaseline = 'top';

    lines.forEach((line, index) => {
        const lineY = y + headerHeight + (padding / 2) + (index * lineHeight);
        const lineX = x + padding;
        ctx.fillText(line, lineX, 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 Language and Code Integrator is a versatile online tool that allows users to overlay code snippets onto images seamlessly. It enables you to select an image and specify a block of code, which is rendered directly onto the image in a visually appealing format. Customization options include selecting the programming language, adjusting the color theme for the overlay, modifying font size, and choosing the position of the code on the image. This tool is ideal for developers and educators who want to create visually engaging presentations, tutorials, or social media posts by combining visuals with code examples.

Leave a Reply

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