Please bookmark this page to avoid losing your image tool!

Photo Of Frankenstein Monster Scene

(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, stitchCount = 4, stitchColor = '#3d2b1f', tintColor = 'rgba(50, 100, 50, 0.2)', vignetteIntensity = 0.85, grainAmount = 25) {
    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d', { willReadFrequently: true });
    
    const w = originalImg.naturalWidth;
    const h = originalImg.naturalHeight;
    canvas.width = w;
    canvas.height = h;

    // 1. Draw the initial image
    ctx.drawImage(originalImg, 0, 0, w, h);

    // 2. Apply filters: Grayscale, Tint, and Grain (Pixel manipulation)
    const imageData = ctx.getImageData(0, 0, w, h);
    const data = imageData.data;

    // Helper to parse the RGBA tint color string
    const parseRgba = (colorStr) => {
        const match = colorStr.match(/rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*([\d.]+))?\)/);
        if (!match) return { r: 0, g: 0, b: 0, a: 0 };
        return {
            r: parseInt(match[1]),
            g: parseInt(match[2]),
            b: parseInt(match[3]),
            a: match[4] !== undefined ? parseFloat(match[4]) : 1
        };
    };
    const tint = parseRgba(tintColor);

    for (let i = 0; i < data.length; i += 4) {
        // Grayscale using the luminosity method
        const r = data[i];
        const g = data[i + 1];
        const b = data[i + 2];
        const gray = 0.299 * r + 0.587 * g + 0.114 * b;

        // Apply tint by blending the tint color over the grayscale value
        const alpha = tint.a;
        let finalR = gray * (1 - alpha) + tint.r * alpha;
        let finalG = gray * (1 - alpha) + tint.g * alpha;
        let finalB = gray * (1 - alpha) + tint.b * alpha;

        // Add film grain
        const noise = (Math.random() - 0.5) * grainAmount;
        finalR += noise;
        finalG += noise;
        finalB += noise;

        // Clamp values to 0-255 range
        data[i] = Math.max(0, Math.min(255, finalR));
        data[i + 1] = Math.max(0, Math.min(255, finalG));
        data[i + 2] = Math.max(0, Math.min(255, finalB));
    }
    ctx.putImageData(imageData, 0, 0);

    // 3. Draw stitches
    ctx.strokeStyle = stitchColor;
    ctx.lineWidth = Math.max(2, w * 0.004);
    ctx.shadowColor = 'rgba(0, 0, 0, 0.8)';
    ctx.shadowBlur = 8;
    ctx.shadowOffsetX = 2;
    ctx.shadowOffsetY = 2;

    for (let i = 0; i < stitchCount; i++) {
        // Random start and end points for the main stitch line
        const x1 = Math.random() * w * 0.8 + w * 0.1;
        const y1 = Math.random() * h * 0.8 + h * 0.1;
        const x2 = x1 + (Math.random() - 0.5) * w * 0.4;
        const y2 = y1 + (Math.random() - 0.5) * h * 0.4;
        
        ctx.beginPath();
        ctx.moveTo(x1, y1);
        // Use a quadratic curve to make the line less straight
        const midX = (x1 + x2) / 2 + (Math.random() - 0.5) * 40;
        const midY = (y1 + y2) / 2 + (Math.random() - 0.5) * 40;
        ctx.quadraticCurveTo(midX, midY, x2, y2);
        ctx.stroke();

        // Draw the cross-stitches
        const stitchLength = Math.hypot(x2 - x1, y2 - y1);
        const numCrossStitches = Math.floor(stitchLength / (w * 0.04));
        const dx = (x2 - x1) / stitchLength;
        const dy = (y2 - y1) / stitchLength;
        const crossLineWidth = ctx.lineWidth * 0.75;
        
        for (let j = 1; j < numCrossStitches; j++) {
            const p = j / numCrossStitches;
            // Get point along the curved line (approximation)
            const t = p;
            const px = Math.pow(1 - t, 2) * x1 + 2 * (1 - t) * t * midX + Math.pow(t, 2) * x2;
            const py = Math.pow(1 - t, 2) * y1 + 2 * (1 - t) * t * midY + Math.pow(t, 2) * y2;

            const crossSize = Math.max(6, w * 0.015);
            ctx.save();
            ctx.lineWidth = crossLineWidth;
            ctx.beginPath();
            // Perpendicular line
            ctx.moveTo(px - dy * crossSize, py + dx * crossSize);
            ctx.lineTo(px + dy * crossSize, py - dx * crossSize);
            ctx.stroke();
            ctx.restore();
        }
    }
    // Reset shadow for next drawings
    ctx.shadowColor = 'transparent';
    ctx.shadowBlur = 0;
    ctx.shadowOffsetX = 0;
    ctx.shadowOffsetY = 0;

    // 4. Draw vignette
    const centerX = w / 2;
    const centerY = h / 2;
    const outerRadius = Math.sqrt(centerX * centerX + centerY * centerY);
    const gradient = ctx.createRadialGradient(centerX, centerY, outerRadius * (1.1 - vignetteIntensity), centerX, centerY, outerRadius);
    gradient.addColorStop(0, 'rgba(0,0,0,0)');
    gradient.addColorStop(0.5, 'rgba(0,0,0,0.1)');
    gradient.addColorStop(1, 'rgba(0,0,0,0.8)');
    ctx.fillStyle = gradient;
    ctx.fillRect(0, 0, w, h);
    
    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 ‘Photo of Frankenstein Monster Scene’ tool allows users to creatively enhance their images by applying a series of artistic effects. This includes transforming the image to grayscale, adding a color tint, introducing grain for texture, drawing stitched lines, and applying a vignette effect to create a dramatic focal point. It is useful for artists, designers, or anyone looking to stylize a photo for artistic projects, social media sharing, or personal collections.

Leave a Reply

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