Please bookmark this page to avoid losing your image tool!

Image To Cross Hatching Art 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 cross-hatching art style.
 *
 * @param {Image} originalImg The original javascript Image object.
 * @param {number} spacing The spacing between the hatching lines. A smaller number means denser lines.
 * @param {number} directions The number of different angles/directions for the hatching lines (e.g., 4 would mean 0°, 45°, 90°, 135°).
 * @param {string} lineColor The color of the hatching lines in a CSS-compatible format (e.g., '#000000' or 'black').
 * @param {string} backgroundColor The background color of the canvas.
 * @param {string} thresholds A comma-separated string of brightness thresholds (0-255). Each threshold corresponds to a hatching direction, determining how dark a pixel needs to be to receive that layer of hatching.
 * @param {number} lineWidth The width of the hatching lines.
 * @returns {HTMLCanvasElement} A canvas element with the cross-hatching art.
 */
function processImage(originalImg, spacing = 6, directions = 4, lineColor = '#000000', backgroundColor = '#ffffff', thresholds = '200,150,100,50,25', lineWidth = 1) {
    const width = originalImg.width;
    const height = originalImg.height;

    // Create a temporary canvas to get pixel data
    const tempCanvas = document.createElement('canvas');
    tempCanvas.width = width;
    tempCanvas.height = height;
    const tempCtx = tempCanvas.getContext('2d', { willReadFrequently: true });
    tempCtx.drawImage(originalImg, 0, 0, width, height);
    const imageData = tempCtx.getImageData(0, 0, width, height).data;

    // Create the output canvas
    const outputCanvas = document.createElement('canvas');
    outputCanvas.width = width;
    outputCanvas.height = height;
    const outputCtx = outputCanvas.getContext('2d');

    // Fill background
    outputCtx.fillStyle = backgroundColor;
    outputCtx.fillRect(0, 0, width, height);

    // Create a 2D array to store the brightness of each pixel
    const brightnessMap = new Array(height).fill(0).map(() => new Array(width).fill(0));
    for (let y = 0; y < height; y++) {
        for (let x = 0; x < width; x++) {
            const index = (y * width + x) * 4;
            const r = imageData[index];
            const g = imageData[index + 1];
            const b = imageData[index + 2];
            // Calculate brightness using a simple average
            const brightness = (r + g + b) / 3;
            brightnessMap[y][x] = brightness;
        }
    }

    // --- Drawing Logic ---

    // Parse thresholds and sort them from darkest to lightest trigger
    const thresholdLevels = thresholds.split(',').map(Number).sort((a, b) => b - a);
    
    // Make sure spacing is at least 1 to avoid infinite loops
    const step = Math.max(1, Math.floor(spacing));

    outputCtx.strokeStyle = lineColor;
    outputCtx.lineWidth = lineWidth;
    outputCtx.lineCap = 'round';

    // Draw lines for each direction
    for (let i = 0; i < directions; i++) {
        // Use the corresponding threshold. If there are more directions than thresholds,
        // reuse the last (strictest) threshold for the extra layers.
        const threshold = thresholdLevels[i] ?? thresholdLevels[thresholdLevels.length - 1];
        if (typeof threshold !== 'number') continue; // Skip if no valid thresholds left

        // Convert angle to radians
        const angle = (i * 180 / directions) * (Math.PI / 180);
        const cosAngle = Math.cos(angle);
        const sinAngle = Math.sin(angle);
        
        // Batch all line segments for this direction into one path for performance
        outputCtx.beginPath();

        // Iterate over the image on a grid defined by the spacing
        for (let y = 0; y < height; y += step) {
            for (let x = 0; x < width; x += step) {
                const brightness = brightnessMap[y][x];

                // If the area is dark enough, draw a line segment
                if (brightness < threshold) {
                    // Make lines slightly shorter than the spacing to avoid a solid grid look
                    const lineLength = step * 0.8; 
                    const dx = (lineLength / 2) * cosAngle;
                    const dy = (lineLength / 2) * sinAngle;

                    outputCtx.moveTo(x - dx, y - dy);
                    outputCtx.lineTo(x + dx, y + dy);
                }
            }
        }
        // Stroke the entire path for this angle at once
        outputCtx.stroke();
    }

    return outputCanvas;
}

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 Cross Hatching Art Converter allows users to transform standard images into unique cross-hatching art styles. This tool provides customization options including line density, color, angle, and line width, enabling the creation of varying artistic effects. It is suitable for artists, designers, and enthusiasts looking to add a distinctive touch to their images, whether for digital artwork, graphic design projects, or social media content.

Leave a Reply

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