Please bookmark this page to avoid losing your image tool!

Image Zone Plate Lens Effect 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,
    centerXRatio = 0.5,
    centerYRatio = 0.5,
    frequency = 10,
    phaseShift = 0, // Radians
    strength = 0.5,
    zoneColor1Str = "rgba(0,0,0,1)",
    zoneColor2Str = "rgba(255,255,255,0)"
) {
    const width = originalImg.width;
    const height = originalImg.height;

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

    if (!ctx) { // Should not happen in a browser environment
        console.error("Could not get 2D context");
        return outputCanvas; // Return an empty canvas
    }
    
    if (width === 0 || height === 0) {
        // For a 0-dimension image (e.g., not loaded or genuinely 0x0),
        // draw nothing and return an empty canvas of that size.
        return outputCanvas;
    }

    // Helper function to parse CSS color strings to an {r, g, b, a} object.
    // Alpha 'a' will be in the range [0, 1].
    function _parseColorToRGBA(colorStr) {
        const tempCanvas = document.createElement('canvas');
        tempCanvas.width = 1;
        tempCanvas.height = 1;
        // {willReadFrequently: true} is an optimization hint for contexts heavily used with getImageData.
        const tempCtx = tempCanvas.getContext('2d', { willReadFrequently: true });

        if (!tempCtx) return { r: 0, g: 0, b: 0, a: 0 }; // Fallback, though unlikely in browsers.

        tempCtx.fillStyle = colorStr; // Assign "invalid-color" will make fillStyle default to black
        tempCtx.fillRect(0, 0, 1, 1);
        const imageData = tempCtx.getImageData(0, 0, 1, 1).data;
        
        return {
            r: imageData[0],
            g: imageData[1],
            b: imageData[2],
            a: imageData[3] / 255.0
        };
    }

    // Draw the original image onto the output canvas first
    ctx.drawImage(originalImg, 0, 0, width, height);

    // Create a temporary canvas for the zone plate pattern
    const zonePlateCanvas = document.createElement('canvas');
    zonePlateCanvas.width = width;
    zonePlateCanvas.height = height;
    const zoneCtx = zonePlateCanvas.getContext('2d', { willReadFrequently: true });

    if (!zoneCtx) { // Should not happen
        console.error("Could not get 2D context for zone plate canvas");
        return outputCanvas; // Return canvas with original image only
    }

    const zoneImageData = zoneCtx.createImageData(width, height);
    const data = zoneImageData.data;

    const actualCenterX = width * centerXRatio;
    const actualCenterY = height * centerYRatio;

    // Calculate the maximum possible distance from the (actualCenterX, actualCenterY)
    // to any of the four corners of the image. This normalizes the radial distance 'r'
    // so that 'frequency' consistently refers to the number of full cycles
    // from the center to the furthest point in the image bounds from that center.
    const distSqToCorners = [
        actualCenterX * actualCenterX + actualCenterY * actualCenterY, // dist to (0,0) squared
        (width - actualCenterX) * (width - actualCenterX) + actualCenterY * actualCenterY, // dist to (width,0) squared
        actualCenterX * actualCenterX + (height - actualCenterY) * (height - actualCenterY), // dist to (0,height) squared
        (width - actualCenterX) * (width - actualCenterX) + (height - actualCenterY) * (height - actualCenterY) // dist to (width,height) squared
    ];
    const maxDistSq = Math.max(...distSqToCorners);
    const maxPossibleRadius = Math.sqrt(maxDistSq);
    
    const parsedColor1 = _parseColorToRGBA(zoneColor1Str);
    const parsedColor2 = _parseColorToRGBA(zoneColor2Str);

    for (let y = 0; y < height; y++) {
        for (let x = 0; x < width; x++) {
            const dx = x - actualCenterX;
            const dy = y - actualCenterY;
            const r = Math.sqrt(dx * dx + dy * dy);

            let waveArg;
            // maxPossibleRadius will be 0 only if width and height are 0, which is handled by the initial check.
            // If it were possible for maxPossibleRadius to be 0 here, we'd need to handle division by zero.
            // However, for any image with width > 0 or height > 0, maxPossibleRadius > 0.
            waveArg = (r / maxPossibleRadius) * frequency * 2 * Math.PI + phaseShift;
            
            const zoneValue = Math.cos(waveArg); // Ranges from -1 to 1

            const idx = (y * width + x) * 4; // Index for the pixel's R channel
            let R, G, B, A;

            if (zoneValue > 0) { // One part of the cycle
                R = parsedColor1.r;
                G = parsedColor1.g;
                B = parsedColor1.b;
                A = parsedColor1.a;
            } else { // The other part of the cycle
                R = parsedColor2.r;
                G = parsedColor2.g;
                B = parsedColor2.b;
                A = parsedColor2.a;
            }

            data[idx]     = R;
            data[idx + 1] = G;
            data[idx + 2] = B;
            // Apply overall strength to the alpha of the selected zone color
            // Ensure alpha is clamped between 0 and 255
            data[idx + 3] = Math.max(0, Math.min(255, Math.round(A * strength * 255)));
        }
    }

    zoneCtx.putImageData(zoneImageData, 0, 0);

    // Blend the generated zone plate pattern onto the original image
    // Default globalCompositeOperation 'source-over' will draw zonePlateCanvas on top.
    // The alpha of the zone plate pixels (controlled by parsedColor.a and strength)
    // will determine how it blends with the underlying original image.
    ctx.drawImage(zonePlateCanvas, 0, 0);

    return outputCanvas;
}

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 Zone Plate Lens Effect Creator allows users to apply a creative zone plate effect to images. By adjusting parameters like center position, frequency, phase shift, and color choices, users can generate artistic variations of their images. This tool can be particularly useful for graphic designers, photographers, and artists looking to add unique visual effects to their work, create abstract designs, or enhance images for presentations and social media sharing.

Leave a Reply

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

Other Image Tools:

Photo Kodak Retina Filter Effect Tool

Image Polaroid 600 Filter Effect Tool

Photo Black and White Yellow Filter Effect Tool

Image Contax G2 Film Camera Render Effect Applicator

Image 110 Film Format Filter Effect Tool

Photo Jupiter-9 Portrait Lens Filter Effect

Image Fujifilm GW690 Texas Leica Filter Effect Application

Image Zeiss T* Coating Filter Effect Tool

Image Hoya R72 Infrared Filter Effect Tool

Image Filter Effect for Zeiss Ikon Contaflex

Photo Olympus Mju-II/Stylus Epic Filter Effect Tool

Image NiSi Nano IR ND Filter Effect Tool

Image Polaroid SX-70 Filter Effect Tool

Image Linhof Technika Filter Effect Tool

Image Lee Big Stopper 10-Stop ND Filter Effect Tool

Image Minolta X-700 Film Camera Render Effect Creator

Image ORWO UN54 Motion Picture Film Effect Applicator

Image Shen-Hao Large Format Filter Effect Tool

Image Impossible Project Polaroid Filter Effect Tool

Photo Foma Retropan 320 Film Filter Effect Tool

Image Fuji QuickSnap Disposable Filter Effect Application

Image 220 Film Format Filter Effect

Image Black and White with Green #61 Filter Effect Tool

Image 35mm Panoramic Camera Filter Effect Tool

Image Hitech Firecrest ND Filter Effect Formatter

Photo Rodenstock Digital Vario ND Filter Effect Tool

Image Leica Yellow Filter Effect Application

Image Argus C3 Vintage Camera Filter Effect

Image ORWO NP22 Film Filter Effect Application

Image Wratten #25 Red Filter Effect Tool

Image Helios 44-2 Swirly Bokeh Effect Filter

Image Fujifilm ETERNA Motion Picture Film Effect Applicator

Image Fujifilm FP-100C Instant Film Effect Filter

Image Canon AE-1 Film Camera Render Effect

Photo B+W Dark Red #29 Filter Effect Application

Image Toy Camera Effect Enhancer

See All →