Please bookmark this page to avoid losing your image tool!

Тучка Birthday Image Creator

(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.
function processImage(originalImg, text = "С Днем Рождения, Тучка!", themeColor = "#64b5f6", balloonsCount = 10) {
    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d');
    const width = originalImg.width;
    const height = originalImg.height;

    canvas.width = width;
    canvas.height = height;

    // 1. Draw the base original image
    ctx.drawImage(originalImg, 0, 0, width, height);

    // Dynamic scale based on image dimensions to keep decorations proportional
    const scale = Math.max(0.5, Math.min(width, height) / 800);

    // 2. Draw a decorative thematic frame
    ctx.lineWidth = 30 * scale;
    ctx.strokeStyle = themeColor;
    ctx.strokeRect(0, 0, width, height);
    
    // Inner thin line for the frame
    ctx.lineWidth = 5 * scale;
    ctx.strokeStyle = '#ffffff';
    ctx.strokeRect(15 * scale, 15 * scale, width - 30 * scale, height - 30 * scale);

    // Defined party colors
    const colors = ['#fce18a', '#ff726d', '#b48def', '#f4306d', '#42b983', '#ffffff', '#00b8ff'];

    // 3. Draw Confetti (concentrated near top and bottom)
    ctx.globalAlpha = 0.8;
    for (let i = 0; i < 150; i++) {
        let cx = Math.random() * width;
        let cy = (Math.random() < 0.6)
            ? Math.random() * (height * 0.35)
            : height - Math.random() * (height * 0.35);

        ctx.save();
        ctx.translate(cx, cy);
        ctx.rotate(Math.random() * Math.PI * 2);
        let s = (Math.random() * 0.6 + 0.4) * scale;
        ctx.scale(s, s);
        ctx.fillStyle = colors[Math.floor(Math.random() * colors.length)];
        
        if (Math.random() < 0.5) {
            ctx.beginPath();
            ctx.arc(0, 0, 8, 0, Math.PI * 2);
            ctx.fill();
        } else {
            ctx.fillRect(-6, -10, 12, 20);
        }
        ctx.restore();
    }
    ctx.globalAlpha = 1.0;

    // 4. Utility: Draw Cloud
    function drawCloud(cx, cy, s) {
        ctx.save();
        ctx.translate(cx, cy);
        ctx.scale(s, s);
        ctx.shadowColor = 'rgba(0,0,0,0.15)';
        ctx.shadowBlur = 15;
        ctx.shadowOffsetY = 5;

        ctx.fillStyle = '#ffffff';
        ctx.beginPath();
        // A standard cloud shape made of overlapping arcs
        ctx.arc(0, 0, 20, Math.PI * 0.5, Math.PI * 1.5);
        ctx.arc(25, -15, 25, Math.PI * 1, Math.PI * 1.8);
        ctx.arc(55, -20, 30, Math.PI * 1.2, Math.PI * 1.9);
        ctx.arc(85, -10, 20, Math.PI * 1.5, Math.PI * 2);
        ctx.arc(100, 10, 15, Math.PI * 1.5, Math.PI * 0.5);
        ctx.lineTo(0, 25);
        ctx.closePath();
        ctx.fill();
        ctx.restore();
    }

    // Add some cute white clouds floating on top part
    drawCloud(width * 0.05, 80 * scale, scale * 1.5);
    drawCloud(width * 0.65, 50 * scale, scale * 2.0);
    drawCloud(width * 0.35, 25 * scale, scale * 1.2);

    // 5. Utility: Draw Party Balloons
    function drawBalloon(cx, cy, color, s) {
        ctx.save();
        ctx.translate(cx, cy);
        ctx.scale(s, s);

        // String
        ctx.beginPath();
        ctx.moveTo(0, 25);
        ctx.bezierCurveTo(10, 50, -10, 80, 0, 120);
        ctx.strokeStyle = 'rgba(255,255,255,0.8)';
        ctx.lineWidth = 3;
        ctx.stroke();

        // Balloon body
        ctx.beginPath();
        ctx.ellipse(0, 0, 25, 35, 0, 0, Math.PI * 2);
        ctx.fillStyle = color;
        ctx.fill();

        // Shiny Highlight
        ctx.beginPath();
        ctx.ellipse(-10, -12, 6, 12, Math.PI/8, 0, Math.PI * 2);
        ctx.fillStyle = 'rgba(255,255,255,0.4)';
        ctx.fill();

        // Bottom knot
        ctx.beginPath();
        ctx.moveTo(-6, 33);
        ctx.lineTo(6, 33);
        ctx.lineTo(0, 25);
        ctx.fill();
        ctx.restore();
    }

    // Distribute balloons randomly across the top third
    const parsedBalloonCount = Number(balloonsCount) || 10;
    for (let i = 0; i < parsedBalloonCount; i++) {
        let cx = width * (0.05 + Math.random() * 0.9);
        let cy = height * (0.05 + Math.random() * 0.25);
        let color = colors[Math.floor(Math.random() * (colors.length - 1))]; // avoid white balloon
        let s = scale * (0.8 + Math.random() * 0.7);
        drawBalloon(cx, cy, color, s);
    }

    // 6. Utility: "Tuchka" - Little Cloud White Bear illustration
    function drawTuchkaBear(cx, cy, s) {
        ctx.save();
        ctx.translate(cx, cy);
        ctx.scale(s, s);

        ctx.shadowColor = 'rgba(0,0,0,0.3)';
        ctx.shadowBlur = 15;
        ctx.shadowOffsetY = 8;

        // Ears
        ctx.fillStyle = '#fefefe';
        ctx.beginPath(); ctx.arc(-35, -35, 18, 0, Math.PI*2); ctx.fill();
        ctx.beginPath(); ctx.arc(35, -35, 18, 0, Math.PI*2); ctx.fill();

        // Inner Ears
        ctx.shadowColor = 'transparent';
        ctx.fillStyle = '#e1e8f0';
        ctx.beginPath(); ctx.arc(-35, -35, 9, 0, Math.PI*2); ctx.fill();
        ctx.beginPath(); ctx.arc(35, -35, 9, 0, Math.PI*2); ctx.fill();

        // Head Base
        ctx.shadowColor = 'rgba(0,0,0,0.3)';
        ctx.fillStyle = '#fefefe';
        ctx.beginPath();
        ctx.ellipse(0, 0, 55, 48, 0, 0, Math.PI*2);
        ctx.fill();

        // Muzzle
        ctx.shadowColor = 'transparent';
        ctx.fillStyle = '#ffffff';
        ctx.beginPath();
        ctx.ellipse(0, 14, 28, 20, 0, 0, Math.PI*2);
        ctx.fill();

        // Nose
        ctx.fillStyle = '#1a1a1a';
        ctx.beginPath();
        ctx.ellipse(0, 6, 12, 8, 0, 0, Math.PI*2);
        ctx.fill();
        ctx.fillStyle = '#ffffff';
        ctx.beginPath(); ctx.arc(-4, 4, 3, 0, Math.PI*2); ctx.fill(); // Nose shine

        // Eyes
        ctx.fillStyle = '#1a1a1a';
        ctx.beginPath(); ctx.arc(-20, -10, 6, 0, Math.PI*2); ctx.fill();
        ctx.beginPath(); ctx.arc(20, -10, 6, 0, Math.PI*2); ctx.fill();
        ctx.fillStyle = '#ffffff';
        ctx.beginPath(); ctx.arc(-21, -11, 2.5, 0, Math.PI*2); ctx.fill();
        ctx.beginPath(); ctx.arc(19, -11, 2.5, 0, Math.PI*2); ctx.fill();

        // Blush
        ctx.fillStyle = 'rgba(255, 100, 100, 0.3)';
        ctx.beginPath(); ctx.ellipse(-35, 5, 8, 5, 0, 0, Math.PI*2); ctx.fill();
        ctx.beginPath(); ctx.ellipse(35, 5, 8, 5, 0, 0, Math.PI*2); ctx.fill();

        // Cute Mouth
        ctx.strokeStyle = '#1a1a1a';
        ctx.lineWidth = 2.5;
        ctx.beginPath();
        ctx.moveTo(0, 14);
        ctx.lineTo(0, 22);
        ctx.moveTo(0, 22);
        ctx.arc(-8, 22, 8, 0, Math.PI, false);
        ctx.moveTo(0, 22);
        ctx.arc(8, 22, 8, Math.PI, 0, true);
        ctx.stroke();

        // Party Hat
        ctx.fillStyle = '#ff4b4b';
        ctx.beginPath();
        ctx.moveTo(-22, -40);
        ctx.lineTo(22, -40);
        ctx.lineTo(0, -90);
        ctx.closePath();
        ctx.fill();

        // Hat Pom-Pom & Details
        ctx.fillStyle = '#fff';
        ctx.beginPath(); ctx.arc(0, -90, 10, 0, Math.PI*2); ctx.fill();
        ctx.beginPath(); ctx.arc(0, -50, 4, 0, Math.PI*2); ctx.fill();
        ctx.beginPath(); ctx.arc(-10, -65, 4, 0, Math.PI*2); ctx.fill();
        ctx.beginPath(); ctx.arc(10, -75, 4, 0, Math.PI*2); ctx.fill();

        ctx.restore();
    }

    // Place "Tuchka" Bear at the bottom right
    drawTuchkaBear(width - 150 * scale, height - 120 * scale, scale * 2.2);

    // 7. Draw Birthday Message Text Banner
    const fontSize = Math.max(26, Math.floor(width / (text.length * 0.5)));
    ctx.font = `bold ${fontSize}px 'Comic Sans MS', 'Arial Rounded MT Bold', 'Trebuchet MS', sans-serif`;
    
    const bannerWidth = ctx.measureText(text).width + 120 * scale;
    const bannerHeight = fontSize * 2.2;
    const bx = width / 2;
    const by = height - bannerHeight * 1.5;

    ctx.save();
    ctx.shadowColor = 'rgba(0,0,0,0.4)';
    ctx.shadowBlur = 12;
    ctx.shadowOffsetY = 6;
    ctx.fillStyle = themeColor; 

    // Draw pill-shaped banner behind text
    ctx.beginPath();
    const r = bannerHeight / 2;
    ctx.moveTo(bx - bannerWidth / 2 + r, by - bannerHeight / 2);
    ctx.lineTo(bx + bannerWidth / 2 - r, by - bannerHeight / 2);
    ctx.arc(bx + bannerWidth / 2 - r, by, r, -Math.PI / 2, Math.PI / 2);
    ctx.lineTo(bx - bannerWidth / 2 + r, by + bannerHeight / 2);
    ctx.arc(bx - bannerWidth / 2 + r, by, r, Math.PI / 2, -Math.PI / 2);
    ctx.fill();
    ctx.restore();

    // Render Text
    ctx.save();
    ctx.textAlign = 'center';
    ctx.textBaseline = 'middle';
    ctx.fillStyle = '#ffffff';
    
    // Text Stroke to make it pop
    ctx.strokeStyle = 'rgba(0,0,0,0.15)';
    ctx.lineWidth = 5 * scale;
    ctx.strokeText(text, bx, by);
    ctx.fillText(text, bx, by);
    ctx.restore();

    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 Тучка Birthday Image Creator is a fun tool designed to transform your personal photos into festive birthday greetings. It adds celebratory decorations to your uploaded images, including a colorful themed frame, floating clouds, party balloons, and colorful confetti. The tool also features a cute ‘Tuchka’ white bear character wearing a party hat and a customizable text banner with a birthday message. This is ideal for creating personalized digital greeting cards or celebratory social media posts for friends and family.

Leave a Reply

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