Please bookmark this page to avoid losing your image tool!

Image Native American Beadwork 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, beadSizeParam = 10, outlineColor = 'rgba(0,0,0,0.3)', outlineWidthParam = 1) {
    let beadSize = Number(beadSizeParam);
    let outlineWidth = Number(outlineWidthParam);

    // Validate parameters
    if (isNaN(beadSize) || beadSize <= 0) {
        console.warn(`Invalid beadSize: ${beadSizeParam}. Using default 10.`);
        beadSize = 10;
    }
    if (isNaN(outlineWidth) || outlineWidth < 0) {
        console.warn(`Invalid outlineWidth: ${outlineWidthParam}. Using default 1.`);
        outlineWidth = 1;
    }
    if (typeof outlineColor !== 'string') {
        console.warn(`Invalid outlineColor type. Using default 'rgba(0,0,0,0.3)'.`);
        outlineColor = 'rgba(0,0,0,0.3)';
    }

    const outputCanvas = document.createElement('canvas');

    // Check if originalImg is valid and has dimensions
    if (!originalImg || typeof originalImg.width !== 'number' || typeof originalImg.height !== 'number' || originalImg.width === 0 || originalImg.height === 0) {
        console.error("Original image is invalid or has zero dimensions.");
        // Set canvas to a small size or 0x0 if image info is totally missing
        outputCanvas.width = (originalImg && typeof originalImg.width === 'number') ? originalImg.width : 50;
        outputCanvas.height = (originalImg && typeof originalImg.height === 'number') ? originalImg.height : 50;
        if (outputCanvas.width === 0 || outputCanvas.height === 0) {
            outputCanvas.width = 50; outputCanvas.height = 50; // Ensure some drawable area
        }
        
        const errorCtx = outputCanvas.getContext('2d');
        errorCtx.fillStyle = 'lightgray';
        errorCtx.fillRect(0, 0, outputCanvas.width, outputCanvas.height);
        errorCtx.fillStyle = 'red';
        errorCtx.font = '12px Arial';
        errorCtx.textAlign = 'center';
        errorCtx.textBaseline = 'middle';
        errorCtx.fillText('Invalid Image', outputCanvas.width / 2, outputCanvas.height / 2);
        return outputCanvas;
    }
    
    outputCanvas.width = originalImg.width;
    outputCanvas.height = originalImg.height;
    const ctx = outputCanvas.getContext('2d');

    // Create a temporary canvas to get pixel data from the original image
    const sourceCanvas = document.createElement('canvas');
    sourceCanvas.width = originalImg.width;
    sourceCanvas.height = originalImg.height;
    const sourceCtx = sourceCanvas.getContext('2d', { willReadFrequently: true }); // Hint for optimization
    
    try {
        sourceCtx.drawImage(originalImg, 0, 0, originalImg.width, originalImg.height);
    } catch (e) {
        console.error("Error drawing original image to source canvas:", e);
        ctx.fillStyle = 'lightgray';
        ctx.fillRect(0,0, outputCanvas.width, outputCanvas.height);
        ctx.fillStyle = 'red';
        ctx.font = '16px Arial';
        ctx.textAlign = 'center';
        ctx.textBaseline = 'middle';
        ctx.fillText('Error: Could not draw original image.', outputCanvas.width / 2, outputCanvas.height / 2);
        return outputCanvas;
    }

    let imageData;
    try {
        imageData = sourceCtx.getImageData(0, 0, originalImg.width, originalImg.height);
    } catch (e) {
        // This typically happens due to CORS issues if the image is from a different origin
        // and the server doesn't provide appropriate CORS headers.
        console.error("Error getting image data (likely CORS issue):", e);
        ctx.fillStyle = 'lightgray';
        ctx.fillRect(0,0, outputCanvas.width, outputCanvas.height);
        ctx.fillStyle = 'red';
        ctx.font = '16px Arial';
        ctx.textAlign = 'center';
        ctx.textBaseline = 'middle';
        ctx.fillText('Error: Cannot access image pixels (CORS?).', outputCanvas.width / 2, outputCanvas.height / 2);
        return outputCanvas;
    }
    const data = imageData.data;

    // Iterate over the image in blocks of beadSize x beadSize
    for (let y = 0; y < originalImg.height; y += beadSize) {
        for (let x = 0; x < originalImg.width; x += beadSize) {
            let rSum = 0, gSum = 0, bSum = 0, aSum = 0;
            let numPixelsInBlock = 0;

            // Determine the actual width and height of the current block for averaging,
            // important for blocks near the image edges.
            const currentBlockWidth = Math.min(beadSize, originalImg.width - x);
            const currentBlockHeight = Math.min(beadSize, originalImg.height - y);

            // Calculate the average color of the block
            for (let blockPixelY = 0; blockPixelY < currentBlockHeight; blockPixelY++) {
                for (let blockPixelX = 0; blockPixelX < currentBlockWidth; blockPixelX++) {
                    // Calculate the coordinates of the pixel in the original image
                    const sourcePixelX = x + blockPixelX;
                    const sourcePixelY = y + blockPixelY;
                    
                    // Calculate the index in the 1D pixel data array
                    const pixelIndex = (sourcePixelY * originalImg.width + sourcePixelX) * 4;
                    
                    rSum += data[pixelIndex];     // Red
                    gSum += data[pixelIndex + 1]; // Green
                    bSum += data[pixelIndex + 2]; // Blue
                    aSum += data[pixelIndex + 3]; // Alpha
                    numPixelsInBlock++;
                }
            }

            if (numPixelsInBlock > 0) {
                const avgR = Math.floor(rSum / numPixelsInBlock);
                const avgG = Math.floor(gSum / numPixelsInBlock);
                const avgB = Math.floor(bSum / numPixelsInBlock);
                const avgA = Math.floor(aSum / numPixelsInBlock);

                // Center of the bead for this grid cell
                const beadCenterX = x + beadSize / 2;
                const beadCenterY = y + beadSize / 2;
                
                // Radius of the colored part of the bead
                const radius = beadSize / 2;

                if (radius > 0) { // Only draw if bead has some size
                    // Draw the fill (colored part) of the bead
                    ctx.fillStyle = `rgba(${avgR}, ${avgG}, ${avgB}, ${avgA / 255})`;
                    ctx.beginPath(); // Start a new path for this bead
                    ctx.arc(beadCenterX, beadCenterY, radius, 0, 2 * Math.PI);
                    ctx.fill();

                    // Draw the outline of the bead if specified
                    if (outlineWidth > 0 && outlineColor && outlineColor !== 'transparent') {
                        ctx.strokeStyle = outlineColor;
                        ctx.lineWidth = outlineWidth;
                        // The arc path is already defined from the fill, so we just stroke it.
                        ctx.stroke(); 
                    }
                }
            }
        }
    }

    return outputCanvas;
}

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 Native American Beadwork Filter Effect Tool allows users to transform their images into a unique artistic style reminiscent of Native American beadwork. By adjusting parameters such as bead size, outline color, and outline width, users can create visually appealing renditions of their images that mimic the appearance of beads arranged on a canvas. This tool can be useful for artists, designers, and anyone looking to create custom artwork, craft project materials, or personalized gifts with a distinct cultural flair.

Leave a Reply

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