Please bookmark this page to avoid losing your image tool!

Image Mountain Peak 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.
async function processImage(originalImg, strengthParam = 1.0, lightAngleParam = 135, baseLevelParam = 128) {
    // Parse and validate parameters
    // Strength of the effect (how pronounced the "peaks" are)
    let strength = parseFloat(String(strengthParam));
    if (isNaN(strength)) {
        strength = 1.0;
    }

    // Angle of the light source in degrees (0 is right, 90 is top, 135 is top-left, etc.)
    let lightAngle = parseFloat(String(lightAngleParam));
    if (isNaN(lightAngle)) {
        lightAngle = 135.0;
    }

    // Base gray level for mid-tones
    let baseLevel = parseInt(String(baseLevelParam), 10);
    if (isNaN(baseLevel) || baseLevel < 0 || baseLevel > 255) {
        baseLevel = 128;
    }

    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d', { willReadFrequently: true }); // Added willReadFrequently for performance hint
    
    const width = originalImg.naturalWidth || originalImg.width;
    const height = originalImg.naturalHeight || originalImg.height;

    if (width === 0 || height === 0) {
        // Handle cases where image might not be fully loaded or has no dimensions
        console.error("Image dimensions are zero. Cannot process.");
        // Return an empty or minimal canvas
        canvas.width = 1;
        canvas.height = 1;
        return canvas;
    }

    canvas.width = width;
    canvas.height = height;

    ctx.drawImage(originalImg, 0, 0, width, height);
    
    let imageData;
    try {
        imageData = ctx.getImageData(0, 0, width, height);
    } catch (e) {
        console.error("Could not get ImageData, possibly due to CORS policy if image is cross-origin and canvas is tainted.", e);
        // One way to handle this for cross-origin images is to re-fetch the image if it's known to be CORS-enabled
        // or inform user. For now, return original drawn (unprocessed) canvas.
        // Or, if originalImg.src is available and CORS-enabled, try to load it with crossOrigin='anonymous'
        // For this example, we'll just return the canvas with the original image drawn if getImageData fails.
        return canvas;
    }

    const data = imageData.data;
    const outputImageData = ctx.createImageData(width, height);
    const outputData = outputImageData.data;

    // Convert lightAngle from degrees to radians
    const angleRad = lightAngle * Math.PI / 180;

    // Determine offset for neighbor pixel based on light angle
    // lightDx, lightDy point from current pixel TOWARDS the light source direction.
    // The neighbor pixel we compare with is in the OPPOSITE direction of light (i.e., where the shadow would be cast FROM).
    // Or, more simply, (current pixel - neighbor pixel).
    // neighborX/Y = currentX/Y - lightDx/lightDy
    const lightDx = Math.round(Math.cos(angleRad));
    const lightDy = -Math.round(Math.sin(angleRad)); // Y is inverted in graphics sky vs screen coordinates

    for (let y = 0; y < height; y++) {
        for (let x = 0; x < width; x++) {
            const i = (y * width + x) * 4;

            // Current pixel's grayscale value
            const r = data[i];
            const g = data[i + 1];
            const b = data[i + 2];
            // Standard luminance calculation
            const currentGray = 0.299 * r + 0.587 * g + 0.114 * b;

            // Neighbor pixel coordinates to compare with
            const neighborX = x - lightDx;
            const neighborY = y - lightDy;

            let neighborGray;
            if (neighborX >= 0 && neighborX < width && neighborY >= 0 && neighborY < height) {
                const ni = (neighborY * width + neighborX) * 4;
                const nr = data[ni];
                const ng = data[ni + 1];
                const nb = data[ni + 2];
                neighborGray = 0.299 * nr + 0.587 * ng + 0.114 * nb;
            } else {
                // Handle border pixels: assume neighbor has intensity that results in baseLevel output
                // i.e., currentGray - neighborGray = 0
                neighborGray = currentGray;
            }

            // Calculate difference and new pixel value (emboss formula)
            const diff = currentGray - neighborGray;
            let newValue = baseLevel + strength * diff;

            // Clamp value to 0-255 range
            newValue = Math.max(0, Math.min(255, newValue));

            outputData[i]     = newValue; // R
            outputData[i + 1] = newValue; // G
            outputData[i + 2] = newValue; // B
            outputData[i + 3] = data[i + 3]; // Preserve 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 Mountain Peak Filter Effect Tool allows users to apply a distinctive peak-like embossing effect to their images. This tool enhances the visual depth by simulating the appearance of light and shadow, creating a three-dimensional effect. Users can adjust the strength of the embossing effect, the angle of the simulated light source, and the base level for mid-tones. This can be useful for graphic designers, photographers, or anyone looking to add a unique texture and dynamic visual interest to their images, such as for presentations, social media posts, or artistic projects.

Leave a Reply

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