Please bookmark this page to avoid losing your image tool!

Weather Image Analyzer

(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, temperature = '20°C', weatherCondition = 'sunny', location = 'New York') {

    /**
     * Dynamically loads a font from Google Fonts.
     * @param {string} family The font family name.
     * @param {string} url The URL to the font file.
     * @returns {Promise<void>} A promise that resolves when the font is loaded.
     */
    const loadFont = async (family, url) => {
        const fontFace = new FontFace(family, `url(${url})`, {
            style: 'normal',
            weight: '400'
        });
        try {
            await fontFace.load();
            document.fonts.add(fontFace);
        } catch (e) {
            console.error(`Font ${family} could not be loaded:`, e);
            // The browser will use the fallback font specified in the 'font' property.
        }
    };

    /**
     * Draws a sunny lens flare/glow effect.
     * @param {CanvasRenderingContext2D} ctx The canvas context.
     * @param {number} width The canvas width.
     * @param {number} height The canvas height.
     */
    const drawSunnyEffect = (ctx, width, height) => {
        const gradient = ctx.createRadialGradient(width, 0, 0, width, 0, width * 0.8);
        gradient.addColorStop(0, 'rgba(255, 255, 0, 0.35)');
        gradient.addColorStop(1, 'rgba(255, 255, 0, 0)');
        ctx.fillStyle = gradient;
        ctx.fillRect(0, 0, width, height);
    };

    /**
     * Draws a rain effect.
     * @param {CanvasRenderingContext2D} ctx The canvas context.
     * @param {number} width The canvas width.
     * @param {number} height The canvas height.
     */
    const drawRainEffect = (ctx, width, height) => {
        ctx.strokeStyle = 'rgba(174, 194, 224, 0.8)';
        ctx.lineWidth = 1.5;
        ctx.lineCap = 'round';
        const density = Math.min(500, (width * height) / 2000);
        for (let i = 0; i < density; i++) {
            const x = Math.random() * width;
            const y = Math.random() * height;
            const length = Math.random() * 20 + 10;
            ctx.beginPath();
            ctx.moveTo(x, y);
            ctx.lineTo(x - 5, y + length);
            ctx.stroke();
        }
    };

    /**
     * Draws a snow effect.
     * @param {CanvasRenderingContext2D} ctx The canvas context.
     * @param {number} width The canvas width.
     * @param {number} height The canvas height.
     */
    const drawSnowEffect = (ctx, width, height) => {
        ctx.fillStyle = 'rgba(255, 255, 255, 0.9)';
        const density = Math.min(400, (width * height) / 2500);
        for (let i = 0; i < density; i++) {
            const x = Math.random() * width;
            const y = Math.random() * height;
            const radius = Math.random() * 3 + 1;
            ctx.beginPath();
            ctx.arc(x, y, radius, 0, Math.PI * 2, false);
            ctx.fill();
        }
    };

    /**
     * Draws a specific weather icon.
     * @param {CanvasRenderingContext2D} ctx The canvas context.
     * @param {string} condition The weather condition string.
     * @param {number} x The center x-coordinate for the icon.
     * @param {number} y The center y-coordinate for the icon.
     * @param {number} size The approximate size of the icon.
     */
    const drawWeatherIcon = (ctx, condition, x, y, size) => {
        ctx.save();
        ctx.translate(x, y);
        ctx.lineWidth = size * 0.08;
        ctx.lineCap = 'round';

        // Helper function to draw a cloud
        const drawCloud = () => {
            ctx.fillStyle = 'white';
            ctx.strokeStyle = '#f0f0f0';
            ctx.beginPath();
            // Base
            ctx.moveTo(-size * 0.3, size * 0.15);
            ctx.lineTo(size * 0.3, size * 0.15);
            // Bumps
            ctx.arc(-size * 0.18, size * 0.05, size * 0.18, Math.PI * 0.55, Math.PI * 1.85);
            ctx.arc(0, -size * 0.05, size * 0.22, Math.PI * 1.1, Math.PI * 0.1);
            ctx.arc(size * 0.22, size * 0.05, size * 0.19, Math.PI * 1.4, Math.PI * 0.4);
            ctx.closePath();
            ctx.fill();
            ctx.stroke();
        };

        // Helper function to draw a sun
        const drawSun = (offsetX = 0, offsetY = 0, scale = 1) => {
            ctx.save();
            ctx.translate(offsetX, offsetY);
            ctx.scale(scale, scale);
            ctx.fillStyle = '#FFD700';
            ctx.strokeStyle = '#FFD700';
            ctx.beginPath();
            ctx.arc(0, 0, size * 0.25, 0, Math.PI * 2, false);
            ctx.fill();
            for (let i = 0; i < 8; i++) {
                const angle = (i / 8) * Math.PI * 2;
                ctx.beginPath();
                ctx.moveTo(Math.cos(angle) * size * 0.3, Math.sin(angle) * size * 0.3);
                ctx.lineTo(Math.cos(angle) * size * 0.4, Math.sin(angle) * size * 0.4);
                ctx.stroke();
            }
            ctx.restore();
        };


        if (condition.includes('cloud') && condition.includes('sun')) {
            drawSun(-size * 0.15, -size * 0.1, 0.8);
            drawCloud();
        } else if (condition.includes('sun')) {
            drawSun();
        } else if (condition.includes('rain')) {
            drawCloud();
            ctx.strokeStyle = '#7B94B5';
            ctx.beginPath();
            ctx.moveTo(-size * 0.15, size * 0.25);
            ctx.lineTo(-size * 0.1, size * 0.45);
            ctx.moveTo(0, size * 0.25);
            ctx.lineTo(size * 0.05, size * 0.45);
            ctx.moveTo(size * 0.15, size * 0.25);
            ctx.lineTo(size * 0.2, size * 0.45);
            ctx.stroke();
        } else if (condition.includes('snow')) {
            ctx.strokeStyle = 'white';
            const arms = 8;
            for (let i = 0; i < arms; i++) {
                const angle = (i / arms) * Math.PI * 2;
                ctx.beginPath();
                ctx.moveTo(0, 0);
                ctx.lineTo(Math.cos(angle) * size * 0.4, Math.sin(angle) * size * 0.4);
                // Sub-branches
                let x1 = Math.cos(angle) * size * 0.2;
                let y1 = Math.sin(angle) * size * 0.2;
                let pAngle1 = angle + Math.PI / 4;
                let pAngle2 = angle - Math.PI / 4;
                ctx.moveTo(x1, y1);
                ctx.lineTo(x1 + Math.cos(pAngle1) * size * 0.15, y1 + Math.sin(pAngle1) * size * 0.15);
                ctx.moveTo(x1, y1);
                ctx.lineTo(x1 + Math.cos(pAngle2) * size * 0.15, y1 + Math.sin(pAngle2) * size * 0.15);

                ctx.stroke();
            }
        } else if (condition.includes('cloud')) {
            drawCloud();
        }
        ctx.restore();
    };

    // --- Main Function Logic ---

    const FONT_FAMILY = 'Roboto';
    if (!document.fonts.check(`12px ${FONT_FAMILY}`)) {
        await loadFont(FONT_FAMILY, 'https://fonts.gstatic.com/s/roboto/v30/KFOmCnqEu92Fr1Mu4mxK.woff2');
    }

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

    const condition = weatherCondition.toLowerCase();

    // 1. Apply base filter and draw original image
    if (condition.includes('cloud') || condition.includes('rain') || condition.includes('snow')) {
        ctx.filter = 'grayscale(30%) brightness(95%)';
    }
    ctx.drawImage(originalImg, 0, 0);
    ctx.filter = 'none'; // Reset filter for subsequent drawings

    // 2. Apply cosmetic weather effect overlay
    if (condition.includes('rain')) {
        drawRainEffect(ctx, canvas.width, canvas.height);
    } else if (condition.includes('snow')) {
        drawSnowEffect(ctx, canvas.width, canvas.height);
    } else if (condition.includes('sun')) {
        drawSunnyEffect(ctx, canvas.width, canvas.height);
    }

    // 3. Draw information display panel
    const padding = Math.min(canvas.width, canvas.height) * 0.04;
    const iconSize = Math.min(canvas.width, canvas.height) * 0.1;
    const tempTextSize = Math.min(canvas.width, canvas.height) * 0.07;
    const locationTextSize = tempTextSize * 0.6;

    // Calculate dynamic size for the background panel
    ctx.font = `bold ${tempTextSize}px ${FONT_FAMILY}, sans-serif`;
    const tempWidth = ctx.measureText(temperature).width;
    ctx.font = `bold ${locationTextSize}px ${FONT_FAMILY}, sans-serif`;
    const locWidth = ctx.measureText(location).width;

    const infoBoxWidth = padding + Math.max(locWidth, tempWidth + iconSize + padding) + padding;
    const infoBoxHeight = padding + locationTextSize + tempTextSize + padding;

    // Draw panel background
    ctx.fillStyle = 'rgba(0, 0, 0, 0.45)';
    ctx.strokeStyle = 'rgba(255, 255, 255, 0.5)';
    ctx.lineWidth = 2;
    ctx.beginPath();
    ctx.roundRect(padding, padding, infoBoxWidth, infoBoxHeight, 15);
    ctx.fill();
    ctx.stroke();

    // Draw text and icon
    ctx.fillStyle = 'white';
    ctx.textBaseline = 'top';
    ctx.textAlign = 'left';

    // Location Text
    const locX = padding * 2;
    const locY = padding * 2;
    ctx.font = `bold ${locationTextSize}px ${FONT_FAMILY}, sans-serif`;
    ctx.fillText(location, locX, locY);

    // Temperature Text
    const tempX = locX;
    const tempY = locY + locationTextSize + 5;
    ctx.font = `bold ${tempTextSize}px ${FONT_FAMILY}, sans-serif`;
    ctx.fillText(temperature, tempX, tempY);

    // Weather Icon
    const iconX = tempX + tempWidth + padding;
    const iconY = tempY + tempTextSize / 2;
    drawWeatherIcon(ctx, condition, iconX, iconY, iconSize);

    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 Weather Image Analyzer is an online tool that allows users to upload images and apply weather-themed visual effects based on specified weather conditions. Users can input parameters such as temperature, weather type (e.g., sunny, rainy, snowy), and location, and the tool will generate an image that reflects these conditions through overlays like sunny flares, rain drops, or snowflakes. This tool is useful for creating customized images for weather reports, social media posts, or creative projects that require a specific weather aesthetic.

Leave a Reply

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