Please bookmark this page to avoid losing your image tool!

Image Aboriginal Dot Painting 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, dotRadius = 5, spacing = 15, paletteColorsStr = "#5C2D1E,#D9A05B,#FFFFFF,#2E2E2E,#A74A27,#E8B64B", jitter = 2, sizeVariation = 1, backgroundColor = "#000000") {
    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d', { willReadFrequently: true }); // willReadFrequently for getImageData performance
    
    canvas.width = originalImg.naturalWidth || originalImg.width;
    canvas.height = originalImg.naturalHeight || originalImg.height;

    if (canvas.width === 0 || canvas.height === 0) {
        // Handle cases where image dimensions are not yet available or invalid
        console.error("Image has zero width or height.");
        return canvas; // Return empty canvas
    }

    // 1. Draw original image to a temporary canvas to get pixel data reliably
    // This step is crucial because originalImg might be an HTMLImageElement
    // not yet fully decoded or on a different canvas, and direct getImageData
    // from it might be problematic or restricted.
    const tempCanvas = document.createElement('canvas');
    const tempCtx = tempCanvas.getContext('2d', { willReadFrequently: true });
    tempCanvas.width = canvas.width;
    tempCanvas.height = canvas.height;
    tempCtx.drawImage(originalImg, 0, 0, canvas.width, canvas.height);
    let imageData;
    try {
        imageData = tempCtx.getImageData(0, 0, canvas.width, canvas.height);
    } catch (e) {
        console.error("Error getting image data: ", e);
        // Potentially a CORS issue if image is from another domain and canvas is tainted
        // Fallback: fill with background and return
        ctx.fillStyle = backgroundColor;
        ctx.fillRect(0, 0, canvas.width, canvas.height);
        return canvas;
    }
    const data = imageData.data;

    // 2. Fill the main canvas with background color
    ctx.fillStyle = backgroundColor;
    ctx.fillRect(0, 0, canvas.width, canvas.height);

    // Helper: Hex to RGB
    function hexToRgb(hex) {
        const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
        return result ? {
            r: parseInt(result[1], 16),
            g: parseInt(result[2], 16),
            b: parseInt(result[3], 16)
        } : null;
    }

    // Parse palette colors
    const palette = paletteColorsStr.split(',')
        .map(hex => hex.trim())
        .map(hexToRgb)
        .filter(Boolean); // Remove nulls from invalid hex codes

    if (palette.length === 0) {
        // Fallback minimal palette if provided string is empty or all invalid
        palette.push({ r: 0, g: 0, b: 0 }, { r: 255, g: 255, b: 255 });
    }

    // Helper: Calculate color distance (squared Euclidean distance is fine for comparison)
    function colorDistanceSquared(color1, color2) {
        const dr = color1.r - color2.r;
        const dg = color1.g - color2.g;
        const db = color1.b - color2.b;
        return dr * dr + dg * dg + db * db;
    }

    // Helper: Find closest palette color
    function findClosestPaletteColor(rgbSample, paletteRgbArray) {
        let closestColor = paletteRgbArray[0];
        let minDistance = colorDistanceSquared(rgbSample, closestColor);

        for (let i = 1; i < paletteRgbArray.length; i++) {
            const distance = colorDistanceSquared(rgbSample, paletteRgbArray[i]);
            if (distance < minDistance) {
                minDistance = distance;
                closestColor = paletteRgbArray[i];
            }
        }
        return `rgb(${closestColor.r},${closestColor.g},${closestColor.b})`;
    }
    
    // Ensure numeric parameters and apply constraints
    const numDotRadius = Math.max(0.5, Number(dotRadius)); // Min radius 0.5 for tiny dots
    const numSpacing = Math.max(1, Number(spacing));
    const numJitter = Math.max(0, Number(jitter));
    const numSizeVariation = Math.max(0, Number(sizeVariation));

    // 3. Draw dots
    for (let y = 0; y < canvas.height; y += numSpacing) {
        for (let x = 0; x < canvas.width; x += numSpacing) {
            // Jitter position: add random offset within [-numJitter, +numJitter]
            const currentX = x + (Math.random() * 2 - 1) * numJitter;
            const currentY = y + (Math.random() * 2 - 1) * numJitter;

            // Vary size: add random variation within [-numSizeVariation, +numSizeVariation]
            let currentRadius = numDotRadius + (Math.random() * 2 - 1) * numSizeVariation;
            currentRadius = Math.max(0.5, currentRadius); // Ensure radius is at least 0.5

            // Get color from original image at grid point (x, y)
            // Clamp coordinates to be within image bounds and convert to integer for pixel array access
            const sampleX = Math.min(Math.max(0, Math.floor(x)), canvas.width - 1);
            const sampleY = Math.min(Math.max(0, Math.floor(y)), canvas.height - 1);
            
            const pixelIndex = (sampleY * canvas.width + sampleX) * 4;
            const r = data[pixelIndex];
            const g = data[pixelIndex + 1];
            const b = data[pixelIndex + 2];
            // const a = data[pixelIndex + 3]; // Alpha, could be used for density/opacity if desired

            const sampledColor = { r, g, b };
            const dotColor = findClosestPaletteColor(sampledColor, palette);

            ctx.beginPath();
            ctx.arc(currentX, currentY, currentRadius, 0, Math.PI * 2);
            ctx.fillStyle = dotColor;
            ctx.fill();
        }
    }

    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 Aboriginal Dot Painting Filter Effect Tool allows users to transform images into artwork that mimics the style of Aboriginal dot painting. This tool processes an uploaded image and applies a stippling effect, creating a visually unique version using colorful dots that represent the original image’s colors. Users can adjust parameters such as the radius and spacing of the dots, select a color palette, and modify variations in dot size to achieve their desired artistic effect. This tool is ideal for artists, designers, and enthusiasts looking to create distinctive visual graphics or art pieces that celebrate indigenous art forms.

Leave a Reply

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