Please bookmark this page to avoid losing your image tool!

Image To Prime Number Representation 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.
function processImage(originalImg, primeColorStr = "255,255,255", nonPrimeColorStr = "0,0,0", intensityMode = "average") {

    // Precomputed primes up to 255 for quick lookup
    // Sourced from a standard list of prime numbers.
    const PRIMES_UP_TO_255 = new Set([
        2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 
        67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 
        139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 
        211, 223, 227, 229, 233, 239, 241, 251
    ]);

    /**
     * Checks if a number is prime using the precomputed set.
     * @param {number} num The number to check (expected to be 0-255).
     * @returns {boolean} True if the number is prime, false otherwise.
     */
    function isPrime(num) {
        return PRIMES_UP_TO_255.has(num);
    }

    /**
     * Parses a color string "R,G,B" into an array [R, G, B].
     * @param {string} colorStr The string to parse.
     * @param {number} defaultR Default red component.
     * @param {number} defaultG Default green component.
     * @param {number} defaultB Default blue component.
     * @returns {number[]} Array [R, G, B] of color components.
     */
    function parseColorArray(colorStr, defaultR, defaultG, defaultB) {
        try {
            const parts = colorStr.split(',').map(s => {
                const val = parseInt(s.trim(), 10);
                if (isNaN(val) || val < 0 || val > 255) {
                    // This will be caught by the outer try-catch
                    throw new Error(`Invalid color component: ${s.trim()}`);
                }
                return val;
            });
            if (parts.length === 3) {
                return parts;
            }
        } catch (e) {
            // Log error for debugging, then fall through to return default
            console.warn(`Invalid color string "${colorStr}". Using default. Error: ${e.message}`);
        }
        return [defaultR, defaultG, defaultB];
    }

    const primeColor = parseColorArray(primeColorStr, 255, 255, 255);
    const nonPrimeColor = parseColorArray(nonPrimeColorStr, 0, 0, 0);

    const canvas = document.createElement('canvas');
    // Add willReadFrequently hint for potential performance improvement with getImageData
    const ctx = canvas.getContext('2d', { willReadFrequently: true });

    // Ensure originalImg is a valid, loaded image with dimensions
    if (!originalImg || typeof originalImg.naturalWidth === 'undefined' || originalImg.naturalWidth === 0 || originalImg.naturalHeight === 0) {
        // Create a small canvas with an error message
        canvas.width = 200;
        canvas.height = 100;
        ctx.font = "14px Arial";
        ctx.fillStyle = "red";
        ctx.textAlign = "center";
        ctx.fillText("Invalid or unloaded image", canvas.width / 2, canvas.height / 2);
        console.warn("processImage: Original image is invalid, not loaded, or has zero dimensions.");
        return canvas;
    }
    
    canvas.width = originalImg.naturalWidth;
    canvas.height = originalImg.naturalHeight;

    try {
        ctx.drawImage(originalImg, 0, 0, canvas.width, canvas.height);
    } catch (e) {
        // Handle cases where drawing the image itself fails
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        ctx.font = "16px Arial"; // Use a slightly larger font for errors on potentially larger canvases
        ctx.fillStyle = "red";
        ctx.textAlign = "center";
        // Wrap text if canvas is narrow using maxWidth argument of fillText
        ctx.fillText("Error drawing original image.", canvas.width / 2, canvas.height / 2, canvas.width * 0.9);
        console.error("Error drawing image to canvas: ", e);
        return canvas;
    }

    let imageData;
    try {
        imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
    } catch (e) {
        // Handle errors from getImageData, typically CORS-related
        ctx.clearRect(0, 0, canvas.width, canvas.height); // Clear the successfully drawn image first
        ctx.font = "16px Arial";
        ctx.fillStyle = "red";
        ctx.textAlign = "center";
        let errorMessage = "Error processing image pixels.";
        if (e.name === 'SecurityError') {
            errorMessage = "Cannot process: Image from another domain (CORS issue).";
        }
        ctx.fillText(errorMessage, canvas.width / 2, canvas.height / 2, canvas.width * 0.9);
        console.error("Error calling getImageData: ", e);
        return canvas;
    }
    
    const data = imageData.data;
    const outputImageData = ctx.createImageData(canvas.width, canvas.height);
    const outputData = outputImageData.data;

    for (let i = 0; i < data.length; i += 4) {
        const r = data[i];
        const g = data[i + 1];
        const b = data[i + 2];
        const a = data[i + 3]; // Original alpha

        let valueToCheck;
        switch (intensityMode.toLowerCase()) {
            case "red":
                valueToCheck = r;
                break;
            case "green":
                valueToCheck = g;
                break;
            case "blue":
                valueToCheck = b;
                break;
            case "luminance": // Weighted average for perceived brightness
                valueToCheck = Math.round(0.299 * r + 0.587 * g + 0.114 * b);
                break;
            case "max": // Maximum of R, G, B
                valueToCheck = Math.max(r, g, b);
                break;
            case "min": // Minimum of R, G, B
                valueToCheck = Math.min(r, g, b);
                break;
            case "average": // Simple average of R, G, B
            default:
                valueToCheck = Math.round((r + g + b) / 3);
                break;
        }

        // Ensure valueToCheck is within the 0-255 range (it should be, but clamp as a safeguard)
        valueToCheck = Math.max(0, Math.min(255, valueToCheck));

        const isValPrime = isPrime(valueToCheck);
        const targetColor = isValPrime ? primeColor : nonPrimeColor;

        outputData[i]     = targetColor[0]; // Set R
        outputData[i + 1] = targetColor[1]; // Set G
        outputData[i + 2] = targetColor[2]; // Set B
        outputData[i + 3] = a;              // Preserve original alpha
    }

    ctx.putImageData(outputImageData, 0, 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 Prime Number Representation Converter is a tool designed to visually transform any uploaded image by converting its pixel colors based on the primality of their intensity values. Users can specify colors for prime and non-prime pixel values, allowing for creative image manipulation. This tool is useful for educators, artists, and programmers looking to explore mathematical concepts through visual media, or for anyone interested in generating unique, visually striking representations of images based on mathematical properties.

Leave a Reply

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