Please bookmark this page to avoid losing your image tool!

Image Pixel To Curve 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 a stylized representation using small line segments
 * whose angles are determined by the brightness of the image's pixels.
 * This creates a texture that resembles flowing curves.
 *
 * @param {HTMLImageElement} originalImg The original image element to process.
 * @param {number} stepSize The size of the grid cell for sampling pixels. A smaller number creates a denser, more detailed effect. Default is 10.
 * @param {number} lineThickness The thickness of the generated curve segments. Default is 1.
 * @param {number} curveFactor A multiplier for the rotation effect. Higher values create more pronounced rotations. Default is 1.
 * @param {string} monochrome A string 'true' or 'false'. If 'true', the output will be in a single color. Default is 'false'.
 * @param {string} lineColor The color of the lines if monochrome is 'true'. Can be any valid CSS color string. Default is '#000000'.
 * @param {string} backgroundColor The background color of the output canvas. Can be any valid CSS color string. Default is '#FFFFFF'.
 * @returns {HTMLCanvasElement} A canvas element with the rendered "curved pixel" art.
 */
function processImage(originalImg, stepSize = 10, lineThickness = 1, curveFactor = 1, monochrome = 'false', lineColor = '#000000', backgroundColor = '#FFFFFF') {
    // 1. Parameter validation and parsing
    const step = Math.max(1, Number(stepSize));
    const lw = Math.max(0.1, Number(lineThickness));
    const cFactor = Number(curveFactor);
    const isMonochrome = monochrome.toString().toLowerCase() === 'true';

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

    // 3. Draw the background color
    ctx.fillStyle = backgroundColor;
    ctx.fillRect(0, 0, canvas.width, canvas.height);

    // 4. Get pixel data from the original image
    // A temporary canvas is used to draw the image, allowing us to access its pixel data.
    const tempCanvas = document.createElement('canvas');
    tempCanvas.width = canvas.width;
    tempCanvas.height = canvas.height;
    // Use { willReadFrequently: true } for performance optimization hint
    const tempCtx = tempCanvas.getContext('2d', { willReadFrequently: true });
    tempCtx.drawImage(originalImg, 0, 0, canvas.width, canvas.height);

    let imageData;
    try {
        imageData = tempCtx.getImageData(0, 0, tempCanvas.width, tempCanvas.height);
    } catch (e) {
        // Handle potential security errors (e.g., tainted canvas from a cross-origin image)
        console.error("Could not get image data. The image might be from a different origin.", e);
        ctx.fillStyle = 'red';
        ctx.font = '16px sans-serif';
        ctx.textAlign = 'center';
        ctx.fillText('Error: Could not process image due to cross-origin restrictions.', canvas.width / 2, canvas.height / 2);
        return canvas;
    }
    const data = imageData.data;

    // 5. Setup drawing styles for the output canvas
    ctx.lineWidth = lw;
    ctx.lineCap = 'round';

    // 6. Iterate through the image pixels in a grid pattern.
    // For each point, draw a short, rotated line segment.
    for (let y = 0; y < canvas.height; y += step) {
        for (let x = 0; x < canvas.width; x += step) {
            // Get the index of the pixel (r, g, b, a) in the flat data array
            const index = (y * canvas.width + x) * 4;

            const r = data[index];
            const g = data[index + 1];
            const b = data[index + 2];
            const a = data[index + 3];

            // Skip pixels that are mostly transparent
            if (a < 128) {
                continue;
            }

            // Calculate the pixel's brightness (luminance) as a value from 0 to 1
            const brightness = (0.299 * r + 0.587 * g + 0.114 * b) / 255;

            // Set the color for the line segment
            ctx.strokeStyle = isMonochrome ? lineColor : `rgba(${r},${g},${b},${a / 255})`;

            // The "curve" is a line segment. Its angle is determined by the pixel's brightness.
            const angle = brightness * Math.PI * 2 * cFactor;

            // Make the line slightly smaller than the grid cell for better visual separation
            const lineLength = step * 0.9;

            // Use save/restore to isolate transformations for each line
            ctx.save();
            // Translate the canvas origin to the center of the current grid cell
            ctx.translate(x + step / 2, y + step / 2);
            // Rotate the canvas context
            ctx.rotate(angle);

            // Draw the line segment centered at the new, rotated origin
            ctx.beginPath();
            ctx.moveTo(-lineLength / 2, 0);
            ctx.lineTo(lineLength / 2, 0);
            ctx.stroke();

            // Restore the canvas context to its original state for the next iteration
            ctx.restore();
        }
    }

    // 7. Return the final canvas with the generated artwork
    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 Pixel To Curve Converter is a tool that transforms your images into stylized representations using flowing line segments. Each segment’s orientation is influenced by the brightness of the respective pixel, resulting in a unique texture that mimics curves. You can customize the output using parameters such as step size for detail, line thickness, and color preferences, including options for monochrome output. This tool is ideal for artists, designers, and anyone looking to create visually intriguing artworks from their images, perfect for graphic design projects, digital art, and unique visual presentations.

Leave a Reply

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