Please bookmark this page to avoid losing your image tool!

Image Droste Effect Filter

(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, 
    iterationsStr = "10", 
    scaleFactorStr = "0.75", 
    centerXStr = "", // Default to image center if empty string / non-numeric
    centerYStr = "", // Default to image center if empty string / non-numeric
    rotationStr = "0") {

    const canvas = document.createElement('canvas');
    
    // Validate originalImg: must be an object with numeric, positive width and height.
    // This typically means an HTMLImageElement that has loaded, or another HTMLCanvasElement.
    if (!originalImg || 
        typeof originalImg.width !== 'number' || originalImg.width <= 0 ||
        typeof originalImg.height !== 'number' || originalImg.height <= 0) {
        
        // Return a small canvas with an error message if image is invalid
        canvas.width = 200; 
        canvas.height = 150;
        const errorCtx = canvas.getContext('2d');
        if (errorCtx) { // Should always be obtainable for '2d'
            errorCtx.fillStyle = '#f0f0f0'; // Light gray background
            errorCtx.fillRect(0, 0, canvas.width, canvas.height);
            errorCtx.fillStyle = '#777';   // Darker gray text for message
            errorCtx.font = '14px Arial';
            errorCtx.textAlign = 'center';
            errorCtx.textBaseline = 'middle';
            errorCtx.fillText('Invalid input image', canvas.width / 2, canvas.height / 2);
        }
        return canvas;
    }
    
    canvas.width = originalImg.width;
    canvas.height = originalImg.height;
    const ctx = canvas.getContext('2d');

    if (!ctx) {
        // This is highly unlikely for '2d' context in modern browsers.
        // If it somehow occurs, the canvas will be blank as created.
        console.error("Failed to get 2D rendering context for the canvas.");
        return canvas; 
    }

    // Parse and set default values for parameters
    let numIterations = parseInt(iterationsStr, 10);
    // Iterations must be a non-negative integer.
    if (isNaN(numIterations) || numIterations < 0) {
        numIterations = 10; // Default iterations
    }

    let scale = parseFloat(scaleFactorStr);
    // Scale factor can be any real number. 
    // For classic Droste, 0 < scale < 1 (shrinking).
    // scale = 0: image vanishes. scale < 0: image flips. scale = 1: size constant. scale > 1: image grows.
    if (isNaN(scale)) {
        scale = 0.75; // Default scale factor for shrinking effect
    }

    let rotationDegrees = parseFloat(rotationStr);
    if (isNaN(rotationDegrees)) {
        rotationDegrees = 0; // Default rotation in degrees
    }
    const rotationRadians = rotationDegrees * Math.PI / 180;

    // centerX and centerY default to the image center if not provided or not valid numbers.
    // parseFloat will convert "" or non-numeric strings to NaN.
    let centerX = parseFloat(centerXStr);
    if (isNaN(centerX)) {
        centerX = originalImg.width / 2;
    }

    let centerY = parseFloat(centerYStr);
    if (isNaN(centerY)) {
        centerY = originalImg.height / 2;
    }
    
    // Begin drawing operations
    // 1. Draw the main, largest image. This serves as the base layer.
    ctx.drawImage(originalImg, 0, 0, originalImg.width, originalImg.height);

    // 2. Sequentially apply transformations and redraw the original image.
    //    Each iteration's transformation is compounded with the previous ones
    //    due to modifications of the Current Transformation Matrix (CTM).
    for (let i = 0; i < numIterations; i++) {
        // The transformation sequence is:
        //   - Translate so the pivot point (centerX, centerY) is at the origin.
        //   - Rotate around this new origin.
        //   - Scale relative to this new origin.
        //   - Translate back, so drawings are relative to canvas top-left but transformed.
        
        ctx.translate(centerX, centerY);
        
        if (rotationRadians !== 0) { // Avoid ctx.rotate(0) call if no rotation
            ctx.rotate(rotationRadians);
        }
        ctx.scale(scale, scale); // Apply uniform scaling
        
        ctx.translate(-centerX, -centerY);
        
        // Draw the original image again. It will be rendered according to the modified CTM.
        // This creates the "image within an image" recursive effect.
        ctx.drawImage(originalImg, 0, 0, originalImg.width, originalImg.height);
    }

    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 Droste Effect Filter is a web-based tool that allows users to create visually striking images featuring the Droste effect, where an image recursively contains smaller versions of itself. Users can specify parameters such as the number of iterations, scaling factor, rotation angle, and the center point of the effect to customize the output. This tool is ideal for graphic designers, artists, and hobbyists looking to create unique visual art, decorative graphics, or engaging digital content. It can be used for creating artwork, social media posts, and other creative projects where a recursive image effect adds intrigue and depth.

Leave a Reply

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