Please bookmark this page to avoid losing your image tool!

Image Crystal Prism Filter Effect Tool

(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 = 10, angle = 0, facetSize = 50, facetStrengthVariation = 0.2, facetAngleVariation = 15) {
    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d');

    const W = originalImg.naturalWidth || originalImg.width;
    const H = originalImg.naturalHeight || originalImg.height;

    if (W === 0 || H === 0) {
        // Image not loaded or zero size, return an empty canvas.
        canvas.width = W;
        canvas.height = H;
        return canvas;
    }
    
    canvas.width = W;
    canvas.height = H;

    // Draw the original image onto the canvas
    ctx.drawImage(originalImg, 0, 0, W, H);

    // If base strength is zero, no displacement effect will occur.
    // Facet variations modify base strength/angle, so if base strength is 0, they also result in 0 displacement.
    if (strength === 0) {
        return canvas;
    }

    const imageData = ctx.getImageData(0, 0, W, H);
    const pixels = imageData.data;
    const outputImageData = ctx.createImageData(W, H);
    const outputPixels = outputImageData.data;

    // Determine if faceting should be applied based on parameters
    const applyFacetStrengthVariation = Math.abs(facetStrengthVariation) > 0.001;
    const applyFacetAngleVariation = Math.abs(facetAngleVariation) > 0.001;
    const useFacets = facetSize > 0 && (applyFacetStrengthVariation || applyFacetAngleVariation);

    // Helper function to get a pseudo-random value (0-1) for a facet cell
    // This ensures consistent randomness for each cell.
    const getFacetRand = (cellX, cellY) => {
        // Constants chosen to create varied patterns.
        const val = Math.sin(cellX * 12.9898 + cellY * 78.233 + W * 0.0113 + H * 0.0307) * 43758.5453123;
        return val - Math.floor(val);
    };

    // Helper function to get a pixel channel value from source data,
    // with boundary clamping and rounding of source coordinates.
    const getPixelChannel = (sourceData, imgW, imgH, sX, sY, channelOffset) => {
        // Round coordinates to nearest integer pixel
        const srcX = Math.round(sX);
        const srcY = Math.round(sY);
        
        // Clamp coordinates to be within image bounds
        const clampedX = Math.max(0, Math.min(imgW - 1, srcX));
        const clampedY = Math.max(0, Math.min(imgH - 1, srcY));
        
        const index = (clampedY * imgW + clampedX) * 4;
        return sourceData[index + channelOffset];
    };

    for (let y = 0; y < H; y++) {
        for (let x = 0; x < W; x++) {
            const currentIndex = (y * W + x) * 4;

            let currentStrength = strength;
            let currentAngleDeg = angle;

            if (useFacets) {
                const cellX = Math.floor(x / facetSize);
                const cellY = Math.floor(y / facetSize);
                const facetRand = getFacetRand(cellX, cellY); // Value between 0 and 1

                if (applyFacetStrengthVariation) {
                    // Modulate strength: baseStrength * (1 +/- variation)
                    const strengthFactor = 1 + (facetRand - 0.5) * 2 * facetStrengthVariation;
                    currentStrength = strength * strengthFactor;
                }

                if (applyFacetAngleVariation) {
                    // Modulate angle: baseAngle +/- variationOffset
                    const angleOffsetDeg = (facetRand - 0.5) * 2 * facetAngleVariation;
                    currentAngleDeg = angle + angleOffsetDeg;
                }
            }
            
            // If, after adjustments, strength is effectively zero for this pixel, copy original.
            // Using a small epsilon for floating point comparisons.
            if (Math.abs(currentStrength) < 0.001) { 
                outputPixels[currentIndex + 0] = pixels[currentIndex + 0];
                outputPixels[currentIndex + 1] = pixels[currentIndex + 1];
                outputPixels[currentIndex + 2] = pixels[currentIndex + 2];
                outputPixels[currentIndex + 3] = pixels[currentIndex + 3];
                continue;
            }

            const currentAngleRad = currentAngleDeg * Math.PI / 180;
            const cosAngle = Math.cos(currentAngleRad);
            const sinAngle = Math.sin(currentAngleRad);

            // Calculate the displacement for R and B channels
            const offsetX = currentStrength * cosAngle;
            const offsetY = currentStrength * sinAngle;

            // Source coordinates for Red channel (shifted by +offset)
            const rX = x + offsetX;
            const rY = y + offsetY;

            // Source coordinates for Blue channel (shifted by -offset)
            const bX = x - offsetX;
            const bY = y - offsetY;

            // Green channel and Alpha use the original pixel's location
            const gX = x;
            const gY = y;

            outputPixels[currentIndex + 0] = getPixelChannel(pixels, W, H, rX, rY, 0); // Red
            outputPixels[currentIndex + 1] = getPixelChannel(pixels, W, H, gX, gY, 1); // Green
            outputPixels[currentIndex + 2] = getPixelChannel(pixels, W, H, bX, bY, 2); // Blue
            outputPixels[currentIndex + 3] = getPixelChannel(pixels, W, H, gX, gY, 3); // Alpha
        }
    }

    ctx.putImageData(outputImageData, 0, 0);
    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 Crystal Prism Filter Effect Tool allows users to apply a crystal prism effect to their images, creating visually stunning and vibrant transformations. By adjusting parameters such as strength, angle, facet size, and variations in facet strength and angle, users can customize the intensity and appearance of the effect. This tool can be used for enhancing artwork, creating unique social media posts, or adding artistic flair to photographs and designs.

Leave a Reply

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