Please bookmark this page to avoid losing your image tool!

Image To Watercolor 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 to a watercolor painting effect by applying several layers of filters and blending.
 *
 * @param {HTMLImageElement} originalImg The source image object. It must be fully loaded.
 * @param {number} [blurRadius=8] Controls the amount of color bleeding. Higher values create a softer, more abstract look.
 * @param {number} [textureAmount=0.1] Sets the visibility of the paper texture overlay (a value from 0 to 1).
 * @param {number} [edgeDarken=0.5] Controls the strength of the dark "ink" lines that define edges (a value from 0 to 1).
 * @param {number} [sharpenAmount=0.2] The amount of original image detail blended back to add sharpness (a value from 0 to 1).
 * @returns {HTMLCanvasElement} A new canvas element displaying the image with the watercolor effect.
 */
function processImage(originalImg, blurRadius = 8, textureAmount = 0.1, edgeDarken = 0.5, sharpenAmount = 0.2) {
    const width = originalImg.naturalWidth;
    const height = originalImg.naturalHeight;

    // Helper function to apply a CSS-style filter when drawing a source to a context.
    const applyFilter = (ctx, source, filter) => {
        const w = ctx.canvas.width;
        const h = ctx.canvas.height;
        ctx.filter = filter;
        ctx.drawImage(source, 0, 0, w, h);
        ctx.filter = 'none'; // Reset filter for subsequent operations
    };

    // 1. Create the main canvas for the final output
    const canvas = document.createElement('canvas');
    canvas.width = width;
    canvas.height = height;
    const ctx = canvas.getContext('2d');

    // --- Step 2: Create the base watercolor color layer ---
    // This simulates colors bleeding into each other on wet paper.
    // A blur is applied, then contrast and saturation are increased to make the colors pool and look vibrant.
    applyFilter(ctx, originalImg, `blur(${blurRadius}px) contrast(150%) saturate(150%)`);

    // --- Step 3: Create the "ink line" sketch layer ---
    // This layer simulates the dark lines often seen at the edges of watercolor shapes.
    const sketchCanvas = document.createElement('canvas');
    sketchCanvas.width = width;
    sketchCanvas.height = height;
    const sketchCtx = sketchCanvas.getContext('2d');

    // To create the sketch, we use a classic technique:
    // a. Create a grayscale version of the original image.
    const grayCanvas = document.createElement('canvas');
    grayCanvas.width = width;
    grayCanvas.height = height;
    const grayCtx = grayCanvas.getContext('2d');
    applyFilter(grayCtx, originalImg, 'grayscale(1)');

    // b. Create an inverted and blurred copy of the grayscale image.
    const invertedBlurCanvas = document.createElement('canvas');
    invertedBlurCanvas.width = width;
    invertedBlurCanvas.height = height;
    const ibCtx = invertedBlurCanvas.getContext('2d');
    applyFilter(ibCtx, grayCanvas, 'invert(1) blur(2px)');

    // c. Blend the two layers with "color-dodge" to create a pencil sketch effect.
    sketchCtx.drawImage(grayCanvas, 0, 0);
    sketchCtx.globalCompositeOperation = 'color-dodge';
    sketchCtx.drawImage(invertedBlurCanvas, 0, 0);
    sketchCtx.globalCompositeOperation = 'source-over';

    // d. Invert the result to get dark lines on a white background.
    applyFilter(sketchCtx, sketchCanvas, 'invert(1)');

    // --- Step 4: Blend the sketch layer onto the main color layer ---
    // a 'multiply' blend mode darkens the base layer only where the sketch layer is dark.
    ctx.globalCompositeOperation = 'multiply';
    ctx.globalAlpha = edgeDarken;
    ctx.drawImage(sketchCanvas, 0, 0);
    ctx.globalCompositeOperation = 'source-over';
    ctx.globalAlpha = 1.0;

    // --- Step 5: Add back some detail from the original image ---
    // an 'overlay' blend increases contrast, making details pop and adding texture.
    ctx.globalCompositeOperation = 'overlay';
    ctx.globalAlpha = sharpenAmount;
    ctx.drawImage(originalImg, 0, 0);
    ctx.globalCompositeOperation = 'source-over';
    ctx.globalAlpha = 1.0;

    // --- Step 6: Create and blend a paper texture layer ---
    // We generate random noise to simulate the texture of watercolor paper.
    const textureCanvas = document.createElement('canvas');
    textureCanvas.width = width;
    textureCanvas.height = height;
    const textureCtx = textureCanvas.getContext('2d');
    const noiseData = textureCtx.createImageData(width, height);
    const noisePixels = noiseData.data;

    for (let i = 0; i < noisePixels.length; i += 4) {
        const value = 128 + (Math.random() - 0.5) * 80;
        noisePixels[i] = noisePixels[i + 1] = noisePixels[i + 2] = value;
        noisePixels[i + 3] = 255;
    }
    textureCtx.putImageData(noiseData, 0, 0);
    
    // A slight blur on the noise makes it look more like paper fibers.
    applyFilter(textureCtx, textureCanvas, 'blur(0.5px)');

    // Blend the texture over the entire image.
    ctx.globalCompositeOperation = 'overlay';
    ctx.globalAlpha = textureAmount;
    ctx.drawImage(textureCanvas, 0, 0);
    ctx.globalCompositeOperation = 'source-over';
    ctx.globalAlpha = 1.0;

    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 Watercolor Converter is a tool that transforms your images into a watercolor painting effect. It simulates the natural blending of colors and incorporates a textured overlay to mimic watercolor paper, resulting in vibrant and soft artistic renditions of your photos. Users can customize the effect through parameters such as blur radius, texture amount, edge darkening, and sharpness. This tool is ideal for artists, photographers, or anyone looking to create unique watercolor-style artwork from their images for sharing on social media, printing, or personal projects.

Leave a Reply

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