Please bookmark this page to avoid losing your image tool!

Image Beak And Magic Effect Generator

(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, beakStrength = "50", magicHue = "280", magicIntensity = "50") {
    const canvas = document.createElement("canvas");
    const w = originalImg.width;
    const h = originalImg.height;
    canvas.width = w;
    canvas.height = h;
    const ctx = canvas.getContext("2d");

    // Draw original image to extract pixel data
    ctx.drawImage(originalImg, 0, 0);
    const imgData = ctx.getImageData(0, 0, w, h);
    const data = imgData.data;

    // Output mapped pixel data
    const outputData = new Uint8ClampedArray(data.length);

    // Filter controls
    const bStrength = parseFloat(beakStrength) / 100; // Expected bounds around 0-1
    const mHue = parseFloat(magicHue) % 360;
    const mInt = parseFloat(magicIntensity);
    
    // Geometry logic for the 'beak' distortion
    const cx = w / 2;
    const cy = h / 2;
    const maxR = Math.min(w, h) * 0.45;

    // Helper to get RGB from HSL
    function hslToRgb(h, s, l) {
        let r, g, b;
        if (s === 0) {
            r = g = b = l; // achromatic
        } else {
            const hue2rgb = (p, q, t) => {
                if (t < 0) t += 1;
                if (t > 1) t -= 1;
                if (t < 1/6) return p + (q - p) * 6 * t;
                if (t < 1/2) return q;
                if (t < 2/3) return p + (q - p) * (2/3 - t) * 6;
                return p;
            };
            const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
            const p = 2 * l - q;
            r = hue2rgb(p, q, h + 1/3);
            g = hue2rgb(p, q, h);
            b = hue2rgb(p, q, h - 1/3);
        }
        return [r * 255, g * 255, b * 255];
    }
    
    const magicRGB = hslToRgb(mHue / 360, 1, 0.6);

    // Get bilinearly interpolated pixel values for smoother distortion mapping
    function getPixelBilinear(u, v) {
        let x0 = Math.floor(u);
        let y0 = Math.floor(v);
        let x1 = Math.min(x0 + 1, w - 1);
        let y1 = Math.min(y0 + 1, h - 1);

        x0 = Math.max(0, x0);
        y0 = Math.max(0, y0);

        let dx = u - x0;
        let dy = v - y0;

        let w00 = (1 - dx) * (1 - dy);
        let w10 = dx * (1 - dy);
        let w01 = (1 - dx) * dy;
        let w11 = dx * dy;

        let idx00 = (y0 * w + x0) * 4;
        let idx10 = (y0 * w + x1) * 4;
        let idx01 = (y1 * w + x0) * 4;
        let idx11 = (y1 * w + x1) * 4;

        let r = data[idx00] * w00 + data[idx10] * w10 + data[idx01] * w01 + data[idx11] * w11;
        let g = data[idx00+1] * w00 + data[idx10+1] * w10 + data[idx01+1] * w01 + data[idx11+1] * w11;
        let b = data[idx00+2] * w00 + data[idx10+2] * w10 + data[idx01+2] * w01 + data[idx11+2] * w11;
        let a = data[idx00+3] * w00 + data[idx10+3] * w10 + data[idx01+3] * w01 + data[idx11+3] * w11;

        return [r, g, b, a];
    }

    for (let y = 0; y < h; y++) {
        for (let x = 0; x < w; x++) {
            let dx = x - cx;
            let dy = y - cy;
            let r = Math.sqrt(dx * dx + dy * dy);

            let u = x;
            let v = y;

            if (r < maxR && bStrength > 0) {
                let nr = r / maxR;
                let angle = Math.atan2(dy, dx);

                // Downward focusing geometry to simulate a beak pulling down
                let downFactor = Math.max(0, Math.sin(angle)); 
                let sharpen = Math.pow(downFactor, 3);
                let dropoff = Math.pow(1 - nr, 2);

                // Y-pull sources pixels from higher up, pulling the center downwards
                let pullY = bStrength * maxR * 1.5 * sharpen * dropoff;
                v = y - pullY;

                // X-pull sources from further apart symmetrically, pinching horizontally
                let pullX = bStrength * dx * Math.pow(downFactor, 2) * dropoff;
                u = x + pullX;
            }

            let pxColor = getPixelBilinear(u, v);
            let destIdx = (y * w + x) * 4;

            outputData[destIdx] = pxColor[0];
            outputData[destIdx + 1] = pxColor[1];
            outputData[destIdx + 2] = pxColor[2];
            outputData[destIdx + 3] = pxColor[3];

            // Magical Aura Tinting around the beak area
            if (r < maxR && mInt > 0) {
                let tintFactor = Math.pow(1 - (r / maxR), 2) * 0.3 * (mInt / 100);
                outputData[destIdx] += (magicRGB[0] - outputData[destIdx]) * tintFactor;
                outputData[destIdx + 1] += (magicRGB[1] - outputData[destIdx + 1]) * tintFactor;
                outputData[destIdx + 2] += (magicRGB[2] - outputData[destIdx + 2]) * tintFactor;
            }
        }
    }

    const outImgData = new ImageData(outputData, w, h);
    ctx.putImageData(outImgData, 0, 0);

    // Magical effect mapping (Stars and Sparkles overlay)
    function drawMagicStar(context, x, y, size, hue) {
        context.save();
        context.translate(x, y);
        context.rotate(Math.random() * Math.PI); // Randomize tilt
        context.beginPath();

        let spikes = 4;
        let rot = (Math.PI / 2) * 3;
        let step = Math.PI / spikes;

        context.moveTo(0, -size);
        for (let i = 0; i < spikes; i++) {
            context.lineTo(Math.cos(rot) * size, Math.sin(rot) * size);
            rot += step;
            // The inner intersection point of the star
            context.lineTo(Math.cos(rot) * (size * 0.15), Math.sin(rot) * (size * 0.15));
            rot += step;
        }
        context.lineTo(0, -size);
        context.closePath();

        context.shadowBlur = size * 2.5;
        context.shadowColor = `hsl(${hue}, 100%, 65%)`;
        context.fillStyle = "white";
        context.fill();

        context.restore();
    }

    if (mInt > 0) {
        ctx.globalCompositeOperation = "screen"; // Ethereal Magic Bleed
        let numStars = (mInt / 100) * 80; // Scale stars by intensity

        for (let i = 0; i < numStars; i++) {
            // Random clustering focusing near or below center (where the 'beak' drops)
            let rAngle = Math.random() * Math.PI * 2;
            let rDist = Math.random() * maxR * 1.5;
            
            // Bias downwards
            if (Math.sin(rAngle) > 0) rDist *= 0.5;

            let px = cx + Math.cos(rAngle) * rDist;
            let py = cy + Math.sin(rAngle) * rDist;

            let size = Math.random() * (Math.max(w, h) * 0.015) + (Math.max(w, h) * 0.005);
            drawMagicStar(ctx, px, py, size, mHue);
        }
        ctx.globalCompositeOperation = "source-over"; // Reset composite
    }

    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 Beak and Magic Effect Generator is a creative tool that applies stylized geometric distortions and ethereal overlays to your images. It allows you to create a ‘beak’ effect through targeted pixel pulling and pinching, while simultaneously adding a magical aura with customizable color hues and intensity. The tool can generate sparkling star overlays and colored tints to give your photos a fantasy or whimsical feel. This is ideal for digital artists, social media enthusiasts looking to create unique character portraits, or anyone wanting to add surreal, magical elements to their photography.

Leave a Reply

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