Please bookmark this page to avoid losing your image tool!

Tsarevna-lyagushka Image Generator

(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, text = "Царевна-лягушка", themeIntensity = 0.6) {
    return new Promise((resolve) => {
        const canvas = document.createElement('canvas');
        const ctx = canvas.getContext('2d');
        const w = originalImg.width;
        const h = originalImg.height;
        canvas.width = w;
        canvas.height = h;

        const scale = Math.min(w, h);

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

        // 1. Swamp Vignette Overlay (Enchanted Forest feel)
        const intensity = Math.max(0, Math.min(1, parseFloat(themeIntensity) || 0.6));
        const gradient = ctx.createRadialGradient(w / 2, h / 2, scale * 0.2, w / 2, h / 2, scale * 0.8);
        gradient.addColorStop(0, 'rgba(40, 80, 40, 0)'); // Clear inside
        gradient.addColorStop(1, `rgba(15, 55, 25, ${intensity})`); // Dark swampy green edges
        ctx.fillStyle = gradient;
        ctx.fillRect(0, 0, w, h);

        // Helper function: Draw Lily Pads
        function drawLilyPad(x, y, radius, angle) {
            ctx.save();
            ctx.translate(x, y);
            ctx.rotate(angle);
            
            // Pad shadow
            ctx.shadowColor = 'rgba(0,0,0,0.5)';
            ctx.shadowBlur = scale * 0.02;
            ctx.shadowOffsetX = scale * 0.005;
            ctx.shadowOffsetY = scale * 0.005;

            ctx.beginPath();
            // A circle with a wedge removed (pac-man style)
            ctx.arc(0, 0, radius, 0.2, Math.PI * 2 - 0.2);
            ctx.lineTo(0, 0);
            ctx.closePath();
            ctx.fillStyle = '#2E8B57'; // SeaGreen
            ctx.fill();

            // Turn off shadow for strokes
            ctx.shadowColor = 'transparent'; 
            ctx.lineWidth = radius * 0.03;
            ctx.strokeStyle = '#006400'; // DarkGreen
            ctx.stroke();

            // Ribs
            ctx.beginPath();
            for (let i = 1; i <= 5; i++) {
                const ribAngle = (i * (Math.PI * 2 - 0.4)) / 6 + 0.2;
                ctx.moveTo(0, 0);
                ctx.lineTo(Math.cos(ribAngle) * radius * 0.8, Math.sin(ribAngle) * radius * 0.8);
            }
            ctx.strokeStyle = '#3CB371';
            ctx.stroke();
            ctx.restore();
        }

        // Draw lily pads in the bottom corners
        drawLilyPad(w * 0.15, h * 0.85, scale * 0.15, 0.5);
        drawLilyPad(w * 0.85, h * 0.9, scale * 0.2, -0.8);

        // Helper function: Ivan Tsarevich's Arrow sticking into the pad
        function drawArrow(x, y, size) {
            ctx.save();
            ctx.translate(x, y);
            // Angle of arrow stuck in the ground
            ctx.rotate(-Math.PI / 3.5); 
            
            ctx.shadowColor = 'rgba(0,0,0,0.4)';
            ctx.shadowBlur = size * 0.05;
            ctx.shadowOffsetX = size * 0.02;
            ctx.shadowOffsetY = size * 0.02;

            // Shaft
            const shaftLength = size * 1.5;
            const shaftWidth = size * 0.06;
            ctx.fillStyle = '#8B4513'; // SaddleBrown
            ctx.fillRect(-shaftLength, -shaftWidth/2, shaftLength, shaftWidth);

            // Arrow head
            ctx.beginPath();
            ctx.moveTo(0, 0);
            ctx.lineTo(-size * 0.3, -size * 0.15);
            ctx.lineTo(-size * 0.25, 0);
            ctx.lineTo(-size * 0.3, size * 0.15);
            ctx.closePath();
            ctx.fillStyle = '#E0E0E0';
            ctx.fill();
            ctx.strokeStyle = '#A9A9A9';
            ctx.lineWidth = size * 0.01;
            ctx.stroke();

            // Fletching (red feathers at the end)
            ctx.fillStyle = '#B22222'; // FireBrick
            ctx.beginPath();
            ctx.moveTo(-shaftLength + size*0.1, 0);
            ctx.lineTo(-shaftLength - size*0.1, -size * 0.2);
            ctx.lineTo(-shaftLength + size*0.3, 0);
            ctx.lineTo(-shaftLength - size*0.1, size * 0.2);
            ctx.closePath();
            ctx.fill();

            // Gold wraps around the feathers
            ctx.strokeStyle = '#DAA520';
            ctx.lineWidth = size * 0.02;
            ctx.beginPath();
            ctx.moveTo(-shaftLength + size*0.15, -shaftWidth/2);
            ctx.lineTo(-shaftLength + size*0.15, shaftWidth/2);
            ctx.moveTo(-shaftLength + size*0.25, -shaftWidth/2);
            ctx.lineTo(-shaftLength + size*0.25, shaftWidth/2);
            ctx.stroke();

            ctx.restore();
        }

        // Place the arrow deep in the right lily pad
        drawArrow(w * 0.82, h * 0.88, scale * 0.15);

        // Helper function: Royal Crown
        function drawCrown(x, y, width, height) {
            ctx.save();
            ctx.translate(x, y);
            
            ctx.shadowColor = 'rgba(0,0,0,0.6)';
            ctx.shadowBlur = scale * 0.02;
            ctx.shadowOffsetY = scale * 0.01;

            ctx.beginPath();
            // Bottom Base
            ctx.moveTo(-width/2, height/2);
            ctx.lineTo(width/2, height/2);
            // Right outer edge
            ctx.lineTo(width/2 + width*0.15, -height/2 + height*0.3);
            // Right dip
            ctx.lineTo(width/4, height*0.1);
            // Center spike
            ctx.lineTo(0, -height/2);
            // Left dip
            ctx.lineTo(-width/4, height*0.1);
            // Left outer edge
            ctx.lineTo(-width/2 - width*0.15, -height/2 + height*0.3);
            ctx.closePath();

            // Golden gradient
            const grad = ctx.createLinearGradient(0, -height/2, 0, height/2);
            grad.addColorStop(0, '#FFF700');
            grad.addColorStop(0.5, '#FFD700');
            grad.addColorStop(1, '#B8860B');
            ctx.fillStyle = grad;
            ctx.fill();
            
            ctx.lineWidth = width * 0.02;
            ctx.strokeStyle = '#8B6508';
            ctx.stroke();

            // Base Trim
            ctx.beginPath();
            ctx.moveTo(-width/2, height/2);
            ctx.lineTo(width/2, height/2);
            ctx.lineWidth = height * 0.15;
            ctx.lineCap = 'round';
            ctx.strokeStyle = '#FFF8DC'; // Off-white soft trim
            ctx.stroke();

            ctx.shadowColor = 'transparent';
            
            // Draw embedded jewels
            function drawJewel(jx, jy, cr, color) {
                ctx.beginPath();
                ctx.arc(jx, jy, cr, 0, Math.PI*2);
                ctx.fillStyle = color;
                ctx.fill();
                ctx.strokeStyle = '#2F4F4F';
                ctx.lineWidth = cr * 0.1;
                ctx.stroke();
                // Shine reflection
                ctx.beginPath();
                ctx.arc(jx - cr*0.3, jy - cr*0.3, cr*0.2, 0, Math.PI*2);
                ctx.fillStyle = 'rgba(255, 255, 255, 0.8)';
                ctx.fill();
            }

            drawJewel(0, -height/2, width*0.06, '#DC143C'); // Center Red Sapphire
            drawJewel(-width/2 - width*0.15, -height/2 + height*0.3, width*0.04, '#4169E1'); // Left Blue Sapphire
            drawJewel(width/2 + width*0.15, -height/2 + height*0.3, width*0.04, '#4169E1');  // Right Blue Sapphire
            drawJewel(0, height*0.25, width*0.05, '#32CD32'); // Bottom Emerald Green

            ctx.restore();
        }

        // Draw a crown hovering near the top center
        drawCrown(w * 0.5, h * 0.12, scale * 0.2, scale * 0.15);

        // Helper function: Enchanted Fairy Tale Golden Text
        function drawGoldText(txt, x, y, size) {
            ctx.save();
            ctx.font = `bold italic ${size}px "Times New Roman", Times, serif`;
            ctx.textAlign = 'center';
            ctx.textBaseline = 'middle';
            
            // Dark mystical backdrop glow
            ctx.shadowColor = 'rgba(0, 0, 0, 0.85)';
            ctx.shadowBlur = size * 0.2;
            ctx.shadowOffsetX = size * 0.02;
            ctx.shadowOffsetY = size * 0.02;
            
            const grad = ctx.createLinearGradient(0, y - size/2, 0, y + size/2);
            grad.addColorStop(0, '#FFF5EE');   // Pure bright top
            grad.addColorStop(0.3, '#FFD700'); // Gold
            grad.addColorStop(0.7, '#DAA520'); // GoldenRod
            grad.addColorStop(1, '#8B6508');   // Dark rich gold
            
            // Text Stroke (creates fairy tale book styling)
            ctx.lineWidth = size * 0.06;
            ctx.strokeStyle = '#1E3323'; // Dark forest slate
            ctx.lineJoin = 'round';
            ctx.strokeText(txt, x, y);
            
            // Text Fill
            ctx.shadowColor = 'transparent'; 
            ctx.fillStyle = grad;
            ctx.fillText(txt, x, y);

            ctx.restore();
        }

        // Draw Title text typically indicating "Царевна-лягушка"
        if (text && text.trim() !== '') {
            drawGoldText(text, w * 0.5, h * 0.9, scale * 0.09);
        }

        resolve(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 Tsarevna-lyagushka Image Generator is a creative tool that applies a mystical, fairy-tale aesthetic to your uploaded images. It uses a specialized overlay technique to add thematic elements such as a dark swampy vignette, decorative lily pads, a royal golden crown, and an enchanted arrow. Additionally, it can overlay stylized, golden fairytale-style text onto the image. This tool is ideal for users looking to create themed digital art, storybook-style illustrations, or decorative assets for fantasy-themed projects and social media.

Leave a Reply

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