Please bookmark this page to avoid losing your image tool!

Image To Oil Paint Effect 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.
/**
 * Applies an oil painting effect to an image.
 * This effect is achieved by iterating through each pixel and replacing its color
 * with the most frequent color in its neighborhood, creating a smeared, clumpy look
 * characteristic of oil paintings.
 *
 * @param {Image} originalImg The original javascript Image object to apply the effect to.
 * @param {number} [radius=4] The radius of the neighborhood to consider for each pixel. A larger radius simulates a larger brush stroke and results in a more abstract effect.
 * @param {number} [intensity=50] The number of color intensity levels. A lower value simplifies the color palette, creating larger, more uniform patches of color, while a higher value preserves more detail.
 * @returns {HTMLCanvasElement} A new canvas element with the oil painting effect applied.
 */
function processImage(originalImg, radius = 4, intensity = 50) {
    // --- Parameter Validation and Setup ---
    radius = Number(radius);
    intensity = Number(intensity);

    // Ensure radius and intensity have valid, sensible values.
    if (isNaN(radius) || radius < 1) radius = 4;
    if (isNaN(intensity) || intensity < 1) intensity = 50;

    const width = originalImg.width;
    const height = originalImg.height;

    // Create a canvas to work with.
    const canvas = document.createElement('canvas');
    canvas.width = width;
    canvas.height = height;
    const ctx = canvas.getContext('2d', { willReadFrequently: true });
    ctx.drawImage(originalImg, 0, 0);

    const originalImageData = ctx.getImageData(0, 0, width, height);
    const originalData = originalImageData.data;

    const outputImageData = ctx.createImageData(width, height);
    const outputData = outputImageData.data;

    // --- Main Oil Painting Algorithm ---
    for (let y = 0; y < height; y++) {
        for (let x = 0; x < width; x++) {
            const pixelIndex = (y * width + x) * 4;

            // Arrays to store intensity information for the current pixel's neighborhood.
            const intensityCounts = new Array(intensity).fill(0);
            const rSum = new Array(intensity).fill(0);
            const gSum = new Array(intensity).fill(0);
            const bSum = new Array(intensity).fill(0);

            // Iterate over the neighborhood defined by the radius.
            for (let j = -radius; j <= radius; j++) {
                for (let i = -radius; i <= radius; i++) {
                    const neighborY = y + j;
                    const neighborX = x + i;

                    // Check if the neighbor pixel is within the image bounds.
                    if (neighborY >= 0 && neighborY < height && neighborX >= 0 && neighborX < width) {
                        const neighborIndex = (neighborY * width + neighborX) * 4;
                        const r = originalData[neighborIndex];
                        const g = originalData[neighborIndex + 1];
                        const b = originalData[neighborIndex + 2];

                        // Calculate the luminance (intensity) of the neighbor pixel.
                        const luminance = Math.round(r * 0.299 + g * 0.587 + b * 0.114);

                        // Map the 0-255 luminance value to an intensity bin.
                        const bin = Math.min(Math.floor(luminance * intensity / 256), intensity - 1);

                        // Add the pixel's data to the corresponding bin.
                        intensityCounts[bin]++;
                        rSum[bin] += r;
                        gSum[bin] += g;
                        bSum[bin] += b;
                    }
                }
            }

            // Find the bin with the most pixels (the dominant intensity level).
            let maxCount = 0;
            let dominantBinIndex = 0;
            for (let k = 0; k < intensity; k++) {
                if (intensityCounts[k] > maxCount) {
                    maxCount = intensityCounts[k];
                    dominantBinIndex = k;
                }
            }

            // Calculate the average color of the pixels in the dominant bin.
            if (maxCount > 0) {
                outputData[pixelIndex] = rSum[dominantBinIndex] / maxCount;
                outputData[pixelIndex + 1] = gSum[dominantBinIndex] / maxCount;
                outputData[pixelIndex + 2] = bSum[dominantBinIndex] / maxCount;
            } else {
                 // Fallback to the original pixel color if the neighborhood is empty (edge case).
                 outputData[pixelIndex] = originalData[pixelIndex];
                 outputData[pixelIndex + 1] = originalData[pixelIndex + 1];
                 outputData[pixelIndex + 2] = originalData[pixelIndex + 2];
            }
            
            outputData[pixelIndex + 3] = 255; // Set alpha to fully opaque.
        }
    }

    // --- Finalize and Return ---
    // Put the processed pixel data back onto the canvas.
    ctx.putImageData(outputImageData, 0, 0);

    // Return the canvas with the oil painting effect.
    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 Oil Paint Effect Converter transforms your regular images into stunning oil painting effects. By simulating traditional oil painting techniques, this tool allows you to customize the look of your images with adjustable parameters. You can modify the brush stroke size and color intensity to create unique, artistic renditions of your photos. This tool is perfect for artists, designers, and anyone looking to add a creative touch to their images, whether for digital art projects, social media posts, or personal use.

Leave a Reply

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