Please bookmark this page to avoid losing your image tool!

Image To Artistic Painting Converter

(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.
/**
 * Converts an image into an artistic painting by redrawing it with simulated brush strokes.
 * The direction of the strokes follows the general flow of the image content.
 *
 * @param {Image} originalImg The original source image object.
 * @param {number} brushSize The average size of the brush strokes. Default is 8.
 * @param {number} strokeLength The average length of the brush strokes. Default is 12.
 * @param {number} intensity A value between 0 and 1 representing the opacity of each stroke. Lower values create a more layered look. Default is 0.7.
 * @param {number} strokeRandomness A value between 0 and 1 controlling how much the stroke direction varies from the image flow. 0 means strokes strictly follow image gradients, 1 means they are completely random. Default is 0.2.
 * @param {number} saturation A factor to adjust the color saturation of the final painting. 1 means no change. Default is 1.2 (20% more saturated).
 * @returns {HTMLCanvasElement} A new canvas element with the painted version of the image.
 */
function processImage(originalImg, brushSize = 8, strokeLength = 12, intensity = 0.7, strokeRandomness = 0.2, saturation = 1.2) {

    // Create the output canvas
    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d');
    const width = originalImg.naturalWidth;
    const height = originalImg.naturalHeight;
    canvas.width = width;
    canvas.height = height;

    // Create a temporary canvas to get the original image's pixel data
    const tempCanvas = document.createElement('canvas');
    const tempCtx = tempCanvas.getContext('2d');
    tempCanvas.width = width;
    tempCanvas.height = height;
    tempCtx.drawImage(originalImg, 0, 0);
    const imgData = tempCtx.getImageData(0, 0, width, height);
    const pixels = imgData.data;

    // Pre-calculate a luminance map for gradient calculation, which guides stroke direction
    const lumMap = new Float32Array(width * height);
    for (let i = 0; i < pixels.length; i += 4) {
        const r = pixels[i];
        const g = pixels[i + 1];
        const b = pixels[i + 2];
        lumMap[i / 4] = 0.299 * r + 0.587 * g + 0.114 * b; // Standard luminance calculation
    }

    /**
     * Helper function to get the luminance of a pixel, clamping coordinates to be within bounds.
     */
    function getLuminance(x, y) {
        const clampedX = Math.max(0, Math.min(width - 1, Math.round(x)));
        const clampedY = Math.max(0, Math.min(height - 1, Math.round(y)));
        return lumMap[clampedY * width + clampedX];
    }

    // Fill the background with white. This is important for images with transparency.
    ctx.fillStyle = 'white';
    ctx.fillRect(0, 0, width, height);

    // Iterate over the image in a grid to place brush strokes
    const gridStep = Math.max(1, Math.floor(brushSize));

    for (let y = 0; y < height; y += gridStep) {
        for (let x = 0; x < width; x += gridStep) {
            // Add random jitter to the stroke position to break the grid-like pattern
            const jitterX = x + (Math.random() - 0.5) * gridStep;
            const jitterY = y + (Math.random() - 0.5) * gridStep;

            // Get the color from the original image at the stroke's position
            const sampleX = Math.max(0, Math.min(width - 1, Math.round(jitterX)));
            const sampleY = Math.max(0, Math.min(height - 1, Math.round(jitterY)));
            const pixelIndex = (sampleY * width + sampleX) * 4;
            const r = pixels[pixelIndex];
            const g = pixels[pixelIndex + 1];
            const b = pixels[pixelIndex + 2];

            // Calculate the image gradient to determine the stroke's angle
            const gradX = getLuminance(sampleX + 1, sampleY) - getLuminance(sampleX - 1, sampleY);
            const gradY = getLuminance(sampleX, sampleY + 1) - getLuminance(sampleX, sampleY - 1);
            
            // The stroke should be perpendicular to the gradient
            let angle = Math.atan2(gradY, gradX) + (Math.PI / 2);
            // Add controlled randomness to the angle
            angle += (Math.random() - 0.5) * Math.PI * strokeRandomness;

            // Set stroke properties with some slight random variation for a more natural look
            ctx.strokeStyle = `rgba(${r}, ${g}, ${b}, ${intensity})`;
            ctx.lineWidth = (Math.random() * 0.6 + 0.4) * brushSize; // Varies between 40% and 100% of brushSize
            ctx.lineCap = 'round';
            
            // Draw the brush stroke
            const len = (Math.random() * 0.6 + 0.4) * strokeLength;
            const endX = jitterX + Math.cos(angle) * len;
            const endY = jitterY + Math.sin(angle) * len;

            ctx.beginPath();
            ctx.moveTo(jitterX, jitterY);
            ctx.lineTo(endX, endY);
            ctx.stroke();
        }
    }

    // If saturation is not 1, apply it as a final filter
    if (saturation !== 1.0) {
        const finalCanvas = document.createElement('canvas');
        const finalCtx = finalCanvas.getContext('2d');
        finalCanvas.width = width;
        finalCanvas.height = height;
        // The filter property applies to subsequent drawing operations
        finalCtx.filter = `saturate(${saturation})`;
        finalCtx.drawImage(canvas, 0, 0);
        return finalCanvas;
    }

    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 To Artistic Painting Converter transforms your images into artistic paintings by simulating brush strokes. This tool allows users to adjust various parameters, such as brush size, stroke length, intensity, and color saturation, to create unique artistic effects. It is ideal for artists, designers, and hobbyists looking to add a creative touch to their photos or create digital art. Use this tool to enhance your artwork, share on social media, or simply explore different artistic styles.

Leave a Reply

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