Please bookmark this page to avoid losing your image tool!

Image Brush Stroke 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, numStrokes = 7000, avgStrokeLength = 20, avgStrokeWidth = 6, opacity = 0.7) {
    const w = originalImg.naturalWidth;
    const h = originalImg.naturalHeight;

    if (w === 0 || h === 0) {
        console.error("Image has zero width or height. Ensure it is loaded and valid.");
        const emptyCanvas = document.createElement('canvas');
        emptyCanvas.width = 1; // Return a 1x1 canvas for empty image
        emptyCanvas.height = 1;
        return emptyCanvas;
    }

    // Create a source canvas to easily sample pixel data from the original image
    // This is not strictly necessary if originalImg is already on a canvas,
    // but ensures we work with pixel data consistently.
    const srcCanvas = document.createElement('canvas');
    srcCanvas.width = w;
    srcCanvas.height = h;
    const srcCtx = srcCanvas.getContext('2d', { willReadFrequently: true }); // Optimization hint
    srcCtx.drawImage(originalImg, 0, 0);

    // Create the output canvas
    const outCanvas = document.createElement('canvas');
    outCanvas.width = w;
    outCanvas.height = h;
    const outCtx = outCanvas.getContext('2d');

    // Draw the original image onto the output canvas first.
    // Strokes will be painted on top of this.
    outCtx.drawImage(originalImg, 0, 0);

    // Paint strokes
    for (let i = 0; i < numStrokes; i++) {
        // Pick a random position for the stroke's center
        const x = Math.random() * w;
        const y = Math.random() * h;

        // Sample color from the original image at this position
        // Use Math.floor for integer coordinates for getImageData
        const pixelData = srcCtx.getImageData(Math.floor(x), Math.floor(y), 1, 1).data;
        const r = pixelData[0];
        const g = pixelData[1];
        const b = pixelData[2];
        // Alpha from original pixel isn't used; opacity parameter controls stroke transparency

        outCtx.strokeStyle = `rgba(${r}, ${g}, ${b}, ${opacity})`;

        // Vary stroke properties slightly for a more natural look
        const currentLength = avgStrokeLength * (0.7 + Math.random() * 0.6); // Vary length by +/- 30%
        const currentWidth = avgStrokeWidth * (0.7 + Math.random() * 0.6);   // Vary width by +/- 30%
        const angle = Math.random() * Math.PI * 2; // Random angle for the stroke

        outCtx.save(); // Save current canvas state (transform, style)

        // Translate and rotate canvas to draw the stroke
        outCtx.translate(x, y);
        outCtx.rotate(angle);

        // Set stroke properties
        outCtx.lineWidth = Math.max(1, currentWidth); // Ensure lineWidth is at least 1
        outCtx.lineCap = 'round'; // Makes ends of lines rounded, like a brush

        // Draw the stroke as a slightly curved line
        outCtx.beginPath();
        outCtx.moveTo(-currentLength / 2, 0);

        // Add a curve to the stroke
        // Control point for quadratic curve. (Math.random() * 2 - 1) gives range [-1, 1]
        const curveAmount = currentLength * 0.2 * (Math.random() * 2 - 1);
        outCtx.quadraticCurveTo(0, curveAmount, currentLength / 2, 0);
        
        outCtx.stroke(); // Apply the stroke

        outCtx.restore(); // Restore canvas state
    }

    return outCanvas;
}

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 Brush Stroke Filter Effect Tool allows users to apply a unique brush stroke effect to images by overlaying randomly generated strokes in various colors sampled from the original image. This tool is useful for artists and designers looking to create artistic renditions of photographs, add a painterly feel to digital images, or enhance visual presentations with a textured look. Users can customize the number of strokes, stroke length, width, and opacity, providing flexibility to achieve the desired artistic effect.

Leave a Reply

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