Please bookmark this page to avoid losing your image tool!

Image Futurist 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,
    threshold1 = 60,
    threshold2 = 120,
    threshold3 = 180,
    color1Str = "30,0,60",     // Dark Violet/Indigo for shadows
    color2Str = "0,200,255",   // Cyan for mid-darks
    color3Str = "255,0,200",   // Magenta for mid-lights
    color4Str = "255,255,100", // Light Yellow for highlights
    numLines = 30,
    lineColorStr = "255,255,255,0.5", // Semi-transparent White for lines
    lineThickness = 2
) {
    // 1. Setup Canvas
    const canvas = document.createElement('canvas');
    // Add willReadFrequently for potential performance optimization with getImageData/putImageData
    const ctx = canvas.getContext('2d', { willReadFrequently: true }); 
    
    const imgWidth = originalImg.naturalWidth || originalImg.width;
    const imgHeight = originalImg.naturalHeight || originalImg.height;

    if (imgWidth === 0 || imgHeight === 0) {
        console.error("Image has zero dimensions. Cannot process.");
        // Return a tiny placeholder canvas
        canvas.width = 1; 
        canvas.height = 1;
        ctx.fillRect(0,0,1,1); // Make it black
        return canvas;
    }

    canvas.width = imgWidth;
    canvas.height = imgHeight;
    
    ctx.drawImage(originalImg, 0, 0, imgWidth, imgHeight);

    // Helper function to parse color strings like "r,g,b" or "r,g,b,a"
    // Returns {r, g, b, a} object with values 0-255 for RGB, 0-1 for A.
    function parseColor(colorStr, defaultAlphaForRGB = 1.0) {
        const parts = colorStr.split(',').map(s => parseFloat(s.trim()));
        let r = 0, g = 0, b = 0, a = defaultAlphaForRGB;

        if (parts.length >= 3) {
            if (!isNaN(parts[0])) r = parts[0];
            if (!isNaN(parts[1])) g = parts[1];
            if (!isNaN(parts[2])) b = parts[2];
            
            if (parts.length === 4 && !isNaN(parts[3])) {
                a = parts[3]; // Use provided alpha if 4 parts
            } else if (parts.length === 3) {
                a = defaultAlphaForRGB; // Use defaultAlpha if only RGB provided
            }
        } else {
            console.warn(`Invalid color string: "${colorStr}". Using default (black or transparent black).`);
            // r,g,b are already 0. Alpha is defaultAlphaForRGB.
        }
        
        // Clamp values to valid ranges
        r = Math.max(0, Math.min(255, r));
        g = Math.max(0, Math.min(255, g));
        b = Math.max(0, Math.min(255, b));
        a = Math.max(0, Math.min(1, a)); // Alpha clamped to 0-1
        
        return { r, g, b, a };
    }

    // Parse posterization colors. These are intended to be fully opaque.
    const color1 = parseColor(color1Str, 1.0);
    const color2 = parseColor(color2Str, 1.0);
    const color3 = parseColor(color3Str, 1.0);
    const color4 = parseColor(color4Str, 1.0);

    // 2. Pixel Manipulation (Color Transformation for Futurist Posterization)
    let imageData;
    try {
        imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
    } catch (e) {
        console.error("Could not getImageData (e.g., cross-origin issue if image source is tainted):", e);
        // Return the canvas with the original image drawn if processing fails here
        return canvas; 
    }
    
    const data = imageData.data;

    for (let i = 0; i < data.length; i += 4) {
        const r_orig = data[i];
        const g_orig = data[i + 1];
        const b_orig = data[i + 2];
        const a_orig = data[i + 3];
        
        // Skip fully transparent pixels to preserve them
        if (a_orig === 0) {
            continue;
        }
        
        // Calculate luminance (standard formula for perceived brightness)
        const luminance = 0.299 * r_orig + 0.587 * g_orig + 0.114 * b_orig;

        let targetColor;
        if (luminance < threshold1) {
            targetColor = color1;
        } else if (luminance < threshold2) {
            targetColor = color2;
        } else if (luminance < threshold3) {
            targetColor = color3;
        } else {
            targetColor = color4;
        }

        data[i] = targetColor.r;
        data[i + 1] = targetColor.g;
        data[i + 2] = targetColor.b;
        // Set alpha for the posterized color. Since targetColor.a is 1.0 for color1-4,
        // this makes non-fully-transparent pixels opaque with the new color.
        // If original pixel had some transparency, it becomes opaque.
        data[i + 3] = targetColor.a * 255; 
    }
    ctx.putImageData(imageData, 0, 0);

    // 3. Dynamic Lines Overlay
    if (numLines > 0 && lineThickness > 0) {
        // Parse line color (can include its own alpha)
        const parsedLineColor = parseColor(lineColorStr); 
        ctx.strokeStyle = `rgba(${parsedLineColor.r}, ${parsedLineColor.g}, ${parsedLineColor.b}, ${parsedLineColor.a})`;
        ctx.lineWidth = Math.max(0.1, lineThickness); // Ensure lineWidth is positive
        
        ctx.beginPath(); //Optimize: begin path once for all lines with same style

        for (let i = 0; i < numLines; i++) {
            const x1 = Math.random() * canvas.width;
            const y1 = Math.random() * canvas.height;
            
            const angle = Math.random() * Math.PI * 2; // Random direction
            
            // Calculate a dynamic length for lines, relative to canvas size
            const canvasDiagonal = Math.sqrt(canvas.width * canvas.width + canvas.height * canvas.height);
            // Make lines reasonably long, e.g., 10% to 60% of canvas diagonal
            const length = (Math.random() * 0.5 + 0.1) * canvasDiagonal; 
            
            const x2 = x1 + Math.cos(angle) * length;
            const y2 = y1 + Math.sin(angle) * length;

            ctx.moveTo(x1, y1);
            ctx.lineTo(x2, y2);
        }
        ctx.stroke(); // Draw all lines accumulated in the path
    }

    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 Futurist Filter Effect Tool allows users to apply a unique posterization effect to images, transforming them into colorful, stylized artworks. By manipulating colors based on luminance, this tool can create visually stunning images that feature vibrant shades and dynamic line overlays. Use cases include enhancing digital artwork, creating eye-catching graphics for social media, or simply experimenting with creative expressions in photography. The tool is suitable for artists, designers, and anyone looking to refresh their images with a bold and modern aesthetic.

Leave a Reply

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