Please bookmark this page to avoid losing your image tool!

Image Prism Filter Application

(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, strength = 5, angleDegrees = 0) {
    // Create a new canvas element
    const canvas = document.createElement('canvas');
    // Get the 2D rendering context.
    // { willReadFrequently: true } is an optimization hint useful for frequent getImageData/putImageData calls.
    const ctx = canvas.getContext('2d', { willReadFrequently: true });

    // Get image dimensions. naturalWidth/Height are appropriate for HTMLImageElement.
    const width = originalImg.naturalWidth;
    const height = originalImg.naturalHeight;

    // Handle cases where image might not be fully loaded or is empty.
    // The problem implies a loaded Image object, but this is good practice.
    if (width === 0 || height === 0) {
        console.warn("Original image has zero width or height. Returning a 1x1 canvas.");
        // Return a minimal canvas to avoid errors if this function is part of a chain.
        canvas.width = 1;
        canvas.height = 1;
        return canvas;
    }

    // Set canvas dimensions to match the image
    canvas.width = width;
    canvas.height = height;

    // Draw the original image onto the canvas. This is necessary to access its pixel data.
    ctx.drawImage(originalImg, 0, 0, width, height);

    // Get the ImageData object, which contains the raw pixel data (RGBA components)
    // for every pixel in the canvas.
    const originalImageData = ctx.getImageData(0, 0, width, height);
    const originalData = originalImageData.data; // This is a Uint8ClampedArray

    // Create a new ImageData object to store the processed pixel data
    const resultImageData = ctx.createImageData(width, height);
    const resultData = resultImageData.data;

    // Convert the separation angle from degrees to radians for use with Math.cos/sin
    const angleRad = angleDegrees * Math.PI / 180;

    // Calculate the x and y components of the displacement vector.
    // This vector defines the direction and magnitude of color separation.
    // The 'strength' parameter scales this displacement.
    const dxOffset = Math.cos(angleRad) * strength;
    const dyOffset = Math.sin(angleRad) * strength;

    // Iterate over each pixel of the image
    for (let y = 0; y < height; y++) {
        for (let x = 0; x < width; x++) {
            // Calculate the index for the current pixel (x,y) in the 1D pixel array.
            // Each pixel consists of 4 components (R, G, B, A).
            const currentIndex = (y * width + x) * 4;

            // --- RED CHANNEL SAMPLING ---
            // Calculate source coordinates for the Red channel.
            // The Red channel is shifted by (-dxOffset, -dyOffset) relative to the current pixel.
            let rx = Math.round(x - dxOffset);
            let ry = Math.round(y - dyOffset);
            // Clamp coordinates to ensure they are within the image boundaries.
            rx = Math.max(0, Math.min(width - 1, rx));
            ry = Math.max(0, Math.min(height - 1, ry));
            // Calculate the index for this source pixel in the originalData array.
            const rIndex = (ry * width + rx) * 4;

            // --- GREEN CHANNEL SAMPLING ---
            // The Green channel is sourced from the current pixel's location (no shift).
            const gIndex = currentIndex; // (y * width + x) * 4

            // --- BLUE CHANNEL SAMPLING ---
            // Calculate source coordinates for the Blue channel.
            // The Blue channel is shifted by (+dxOffset, +dyOffset) relative to the current pixel.
            let bx = Math.round(x + dxOffset);
            let by = Math.round(y + dyOffset);
            // Clamp coordinates to ensure they are within the image boundaries.
            bx = Math.max(0, Math.min(width - 1, bx));
            by = Math.max(0, Math.min(height - 1, by));
            // Calculate the index for this source pixel in the originalData array.
            const bIndex = (by * width + bx) * 4;

            // --- Assign new pixel data ---
            // Assign the sampled channel values to the corresponding pixel in the resultData array.
            resultData[currentIndex]     = originalData[rIndex];     // Red component
            resultData[currentIndex + 1] = originalData[gIndex + 1]; // Green component
            resultData[currentIndex + 2] = originalData[bIndex + 2]; // Blue component
            // The Alpha component is typically taken from the central (Green channel's) sample.
            resultData[currentIndex + 3] = originalData[gIndex + 3]; // Alpha component
        }
    }

    // Put the modified pixel data (resultImageData) back onto the canvas
    ctx.putImageData(resultImageData, 0, 0);

    // Return the canvas element with the prism effect applied
    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 Prism Filter Application allows users to apply a unique prism effect to images by manipulating the color channels based on specific parameters like strength and angle. This tool can be useful for creating artistic and visually striking images, enhancing photographs, or adding dynamic effects for creative projects. It is ideal for graphic designers, photographers, and anyone looking to creatively edit and transform their images online.

Leave a Reply

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