Please bookmark this page to avoid losing your image tool!

Image Paper Texture Filter

(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, intensity = 0.15, grainSize = 2, blendMode = 'overlay') {
    // Determine the dimensions of the image
    // For HTMLImageElement, naturalWidth/Height are intrinsic dimensions.
    // For HTMLCanvasElement or other sources, width/height are used.
    const width = originalImg.naturalWidth || originalImg.width;
    const height = originalImg.naturalHeight || originalImg.height;

    // Create the main canvas to draw on
    const canvas = document.createElement('canvas');
    canvas.width = width;
    canvas.height = height;
    const ctx = canvas.getContext('2d');

    // 1. Draw the original image onto the main canvas
    if (width > 0 && height > 0) {
        ctx.drawImage(originalImg, 0, 0, width, height);
    } else {
        // If image has no dimensions (e.g., not loaded or 0x0),
        // we'll return an empty canvas of 0x0 or the specified WxH.
        // No further processing is meaningful.
        return canvas;
    }
    
    // Clamp intensity to the range [0, 1]. Default to 0 if parsing fails.
    const clampedIntensity = Math.max(0, Math.min(1, parseFloat(intensity) || 0));

    // If intensity is 0 (or effectively 0), no texture is applied.
    // Return the canvas with just the original image.
    if (clampedIntensity === 0) {
        return canvas;
    }

    // Ensure grainSize is a positive integer; default to 1 if invalid or less than 1.
    const actualGrainSize = Math.max(1, parseInt(grainSize, 10) || 1);

    // 2. Create noise texture on a temporary canvas
    // This canvas will hold the grayscale noise pattern.
    const noiseCanvas = document.createElement('canvas');
    noiseCanvas.width = width;
    noiseCanvas.height = height;
    
    // Context acquisition with hint for performance if ImageData operations are dominant.
    const noiseCtx = noiseCanvas.getContext('2d', { 
        willReadFrequently: (actualGrainSize <= 1 && width * height > 0) 
    });

    if (actualGrainSize <= 1) {
        // Per-pixel noise: Efficiently create using ImageData for fine grain
        const noiseImageData = noiseCtx.createImageData(width, height);
        const noiseData = noiseImageData.data;
        for (let i = 0; i < noiseData.length; i += 4) {
            // Generate a random grayscale value (0-255)
            const L = Math.floor(Math.random() * 256);
            noiseData[i] = L;     // Red channel
            noiseData[i + 1] = L; // Green channel
            noiseData[i + 2] = L; // Blue channel
            noiseData[i + 3] = 255; // Alpha channel (fully opaque noise)
        }
        noiseCtx.putImageData(noiseImageData, 0, 0);
    } else {
        // Block-based noise: Draw rectangles for larger grains
        for (let y = 0; y < height; y += actualGrainSize) {
            for (let x = 0; x < width; x += actualGrainSize) {
                const L = Math.floor(Math.random() * 256);
                noiseCtx.fillStyle = `rgb(${L},${L},${L})`;
                noiseCtx.fillRect(x, y, actualGrainSize, actualGrainSize);
            }
        }
    }

    // 3. Blend the noise texture onto the main canvas
    ctx.globalAlpha = clampedIntensity; // Set the opacity for the noise layer

    // Validate and set the blend mode
    const validBlendModes = [
        'source-over', 'source-in', 'source-out', 'source-atop',
        'destination-over', 'destination-in', 'destination-out', 'destination-atop',
        'lighter', 'copy', 'xor', 'multiply', 'screen', 'overlay', 'darken',
        'lighten', 'color-dodge', 'color-burn', 'hard-light', 'soft-light',
        'difference', 'exclusion', 'hue', 'saturation', 'color', 'luminosity'
    ];

    if (validBlendModes.includes(blendMode)) {
        ctx.globalCompositeOperation = blendMode;
    } else {
        ctx.globalCompositeOperation = 'overlay'; // Default to 'overlay' if an invalid mode is provided
    }

    ctx.drawImage(noiseCanvas, 0, 0);

    // 4. Reset canvas context properties to defaults for subsequent drawing operations elsewhere
    ctx.globalAlpha = 1.0;
    ctx.globalCompositeOperation = 'source-over'; // Default HTML Canvas blend mode

    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 Paper Texture Filter allows users to apply a textured paper effect to their images. By adjusting parameters such as intensity, grain size, and blend mode, users can create a variety of artistic effects that simulate the look and feel of traditional paper. This tool can be useful for photographers, graphic designers, and artists who want to add a tactile quality to their digital images, enhance backgrounds, or create visually appealing graphics for print and web. Whether for creative projects, presentations, or social media content, this filter offers a simple way to enrich visual media.

Leave a Reply

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