Please bookmark this page to avoid losing your image tool!

Image Monster Surroundings Visualizer

(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.
/**
 * Visualizes "monsters around" an image by drawing procedurally generated monster features
 * like eyes, tentacles, or slimes on top of it.
 *
 * @param {Image} originalImg The original image object to process.
 * @param {string} monsterType The type of monster to draw. Accepts 'eyes', 'tentacles', or 'slimes'. Defaults to 'eyes'.
 * @param {number} monsterCount The number of monsters to draw on the image. Defaults to 10.
 * @param {number} monsterSize The base size of each monster in pixels. Defaults to 50.
 * @param {number} monsterOpacity The opacity of the monsters, from 0 (transparent) to 1 (opaque). Defaults to 0.8.
 * @param {string} monsterColor The color of the monsters in a CSS-compatible format (e.g., '#ff0000', 'red'). Defaults to '#ff0000'.
 * @returns {HTMLCanvasElement} A canvas element with the monsters drawn over the original image.
 */
function processImage(originalImg, monsterType = 'eyes', monsterCount = 10, monsterSize = 50, monsterOpacity = 0.8, monsterColor = '#ff0000') {
    // Parameter validation and coercion
    const count = parseInt(monsterCount, 10) || 10;
    const size = Math.max(5, parseFloat(monsterSize)) || 50;
    const opacity = Math.max(0, Math.min(1, parseFloat(monsterOpacity) || 0.8));

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

    // Draw original image
    ctx.drawImage(originalImg, 0, 0, w, h);

    // Set monster drawing style
    ctx.globalAlpha = opacity;

    // --- Helper drawing functions ---

    const drawEyes = (x, y) => {
        ctx.fillStyle = monsterColor;
        const eyeRadius = size / 5;
        const eyeSpacing = size / 4;

        // Draw the two eye circles
        ctx.beginPath();
        ctx.arc(x - eyeSpacing, y, eyeRadius, 0, 2 * Math.PI);
        ctx.arc(x + eyeSpacing, y, eyeRadius, 0, 2 * Math.PI);
        ctx.fill();

        // Draw pupils looking towards the center of the image
        const dx = w / 2 - x;
        const dy = h / 2 - y;
        const dist = Math.sqrt(dx * dx + dy * dy) || 1;
        const pupilOffsetX = (dx / dist) * (eyeRadius / 2);
        const pupilOffsetY = (dy / dist) * (eyeRadius / 2);
        const pupilRadius = eyeRadius / 2;

        ctx.fillStyle = '#000';
        ctx.beginPath();
        ctx.arc(x - eyeSpacing + pupilOffsetX, y + pupilOffsetY, pupilRadius, 0, 2 * Math.PI);
        ctx.arc(x + eyeSpacing + pupilOffsetX, y + pupilOffsetY, pupilRadius, 0, 2 * Math.PI);
        ctx.fill();
    };

    const drawTentacle = (x, y, edge) => {
        ctx.strokeStyle = monsterColor;
        ctx.lineWidth = Math.max(2, size / 8);
        ctx.lineCap = 'round';
        ctx.beginPath();
        ctx.moveTo(x, y);

        let endX, endY, cp1x, cp1y, cp2x, cp2y;
        const length = size * 1.5;
        const spread = size;

        // Determine control points based on which edge the tentacle originates from
        if (edge === 0) { // Top
            endY = y + length;
            endX = x + (Math.random() - 0.5) * spread;
            cp1y = y + length / 3;
            cp1x = x + (Math.random() - 0.5) * spread;
            cp2y = y + (length * 2) / 3;
            cp2x = x + (Math.random() - 0.5) * spread;
        } else if (edge === 1) { // Right
            endX = x - length;
            endY = y + (Math.random() - 0.5) * spread;
            cp1x = x - length / 3;
            cp1y = y + (Math.random() - 0.5) * spread;
            cp2x = x - (length * 2) / 3;
            cp2y = y + (Math.random() - 0.5) * spread;
        } else if (edge === 2) { // Bottom
            endY = y - length;
            endX = x + (Math.random() - 0.5) * spread;
            cp1y = y - length / 3;
            cp1x = x + (Math.random() - 0.5) * spread;
            cp2y = y - (length * 2) / 3;
            cp2x = x + (Math.random() - 0.5) * spread;
        } else { // Left
            endX = x + length;
            endY = y + (Math.random() - 0.5) * spread;
            cp1x = x + length / 3;
            cp1y = y + (Math.random() - 0.5) * spread;
            cp2x = x + (length * 2) / 3;
            cp2y = y + (Math.random() - 0.5) * spread;
        }

        ctx.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, endX, endY);
        ctx.stroke();
    };

    const drawSlime = (x, y, edge) => {
        ctx.fillStyle = monsterColor;
        
        let centerX = x;
        let centerY = y;
        const radius = size / 2;
        if (edge === 0) centerY += radius;
        if (edge === 1) centerX -= radius;
        if (edge === 2) centerY -= radius;
        if (edge === 3) centerX += radius;

        ctx.beginPath();
        const points = 6 + Math.floor(Math.random() * 5);
        const angleStep = (Math.PI * 2) / points;
        const startAngle = Math.random() * Math.PI * 2;
        
        const getPoint = (angle) => {
             const r = radius * (0.8 + Math.random() * 0.4);
             return {
                 x: centerX + Math.cos(angle) * r,
                 y: centerY + Math.sin(angle) * r,
             };
        };
        
        let p1 = getPoint(startAngle);
        ctx.moveTo(p1.x, p1.y);

        for (let i = 1; i <= points; i++) {
            const p2 = getPoint(startAngle + i * angleStep);
            const midPoint = { x: (p1.x + p2.x) / 2, y: (p1.y + p2.y) / 2 };
            ctx.quadraticCurveTo(p1.x, p1.y, midPoint.x, midPoint.y);
            p1 = p2;
        }
        ctx.closePath();
        ctx.fill();

        // Draw eyes on the slime
        const tempAlpha = ctx.globalAlpha;
        ctx.globalAlpha = Math.min(1.0, opacity + 0.3);
        ctx.fillStyle = '#000';
        const eyeRadius = size / 10;
        const eyeSpacing = size / 8;
        ctx.beginPath();
        ctx.arc(centerX - eyeSpacing, centerY, eyeRadius, 0, 2 * Math.PI);
        ctx.arc(centerX + eyeSpacing, centerY, eyeRadius, 0, 2 * Math.PI);
        ctx.fill();
        ctx.globalAlpha = tempAlpha;
    };


    // --- Main loop to draw monsters ---
    for (let i = 0; i < count; i++) {
        if (monsterType.toLowerCase() === 'eyes') {
            // Eyes can appear anywhere in the image for a spooky effect
            const randomX = Math.random() * w;
            const randomY = Math.random() * h;
            drawEyes(randomX, randomY);
            continue;
        }

        // Other monsters peek from the edges
        const edge = Math.floor(Math.random() * 4); // 0:top, 1:right, 2:bottom, 3:left
        let x, y;

        switch (edge) {
            case 0: x = Math.random() * w; y = 0; break;
            case 1: x = w; y = Math.random() * h; break;
            case 2: x = Math.random() * w; y = h; break;
            case 3: x = 0; y = Math.random() * h; break;
        }

        switch (monsterType.toLowerCase()) {
            case 'tentacles':
                drawTentacle(x, y, edge);
                break;
            case 'slimes':
                drawSlime(x, y, edge);
                break;
        }
    }

    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 Monster Surroundings Visualizer is a creative tool that allows users to enhance their images by adding whimsical monster features such as eyes, tentacles, or slimes. Users can customize the number, size, color, and opacity of the monsters drawn over the original image. This tool is perfect for artists, game developers, or anyone looking to add a playful touch to their images, making it ideal for social media posts, digital art projects, or Halloween-themed content.

Leave a Reply

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