Please bookmark this page to avoid losing your image tool!

Image Query Translator For MS Paint

(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, numColors = 16, blockSize = 4, dithering = 'bayer') {
    // Coerce parameters to their expected types
    const colorCount = Math.max(2, parseInt(numColors, 10));
    const pixelSize = Math.max(1, parseInt(blockSize, 10));
    const ditherType = String(dithering).toLowerCase();

    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d', { willReadFrequently: true });
    const w = originalImg.width;
    const h = originalImg.height;
    canvas.width = w;
    canvas.height = h;

    // --- 1. Pixelation Step ---
    // Downsample the image to create a blocky effect, then scale it back up
    // using nearest-neighbor scaling (imageSmoothingEnabled = false).
    if (pixelSize > 1) {
        const tempCanvas = document.createElement('canvas');
        const tempCtx = tempCanvas.getContext('2d');
        const smallW = Math.ceil(w / pixelSize);
        const smallH = Math.ceil(h / pixelSize);
        tempCanvas.width = smallW;
        tempCanvas.height = smallH;

        // Draw the original image into the small canvas, effectively downsampling it.
        tempCtx.drawImage(originalImg, 0, 0, smallW, smallH);

        // Disable smoothing to get sharp, crisp pixels when scaling up.
        ctx.imageSmoothingEnabled = false;
        
        // Draw the small canvas back onto the main canvas, scaled up.
        ctx.drawImage(tempCanvas, 0, 0, smallW, smallH, 0, 0, w, h);
    } else {
        ctx.drawImage(originalImg, 0, 0);
    }

    // --- 2. Color Reduction and Dithering Step ---
    const imageData = ctx.getImageData(0, 0, w, h);
    const data = imageData.data;

    // --- Helper Function: Generate a color palette ---
    // Creates a generic RGB color cube palette.
    const generatePalette = (count) => {
        const palette = [];
        const levels = Math.round(Math.cbrt(count));
        const step = 255 / (levels - 1);

        if (levels <= 1) {
             return [[0, 0, 0], [255, 255, 255]];
        }
        
        for (let r = 0; r < levels; r++) {
            for (let g = 0; g < levels; g++) {
                for (let b = 0; b < levels; b++) {
                    palette.push([
                        Math.round(r * step),
                        Math.round(g * step),
                        Math.round(b * step)
                    ]);
                }
            }
        }
        return palette;
    };

    const palette = generatePalette(colorCount);

    // --- Helper Function: Find the closest color in the palette ---
    // Uses squared Euclidean distance for efficiency (avoids square roots).
    const findClosestColor = (r, g, b, palette) => {
        let minDistanceSq = Infinity;
        let closestColor = palette[0];
        for (const color of palette) {
            const dR = r - color[0];
            const dG = g - color[1];
            const dB = b - color[2];
            const distanceSq = dR * dR + dG * dG + dB * dB;
            if (distanceSq < minDistanceSq) {
                minDistanceSq = distanceSq;
                closestColor = color;
            }
        }
        return closestColor;
    };

    // --- Dithering Matrix (for Bayer dithering) ---
    // A 4x4 ordered dithering matrix.
    const bayerMatrix = [
        [0, 8, 2, 10],
        [12, 4, 14, 6],
        [3, 11, 1, 9],
        [15, 7, 13, 5]
    ];
    const bayerSize = 4;
    const ditherFactor = 48; // A magic number to control dither intensity

    // --- Process each pixel ---
    for (let i = 0; i < data.length; i += 4) {
        let r = data[i];
        let g = data[i + 1];
        let b = data[i + 2];

        // Apply Bayer dithering if selected
        if (ditherType === 'bayer') {
            const x = (i / 4) % w;
            const y = Math.floor((i / 4) / w);
            const bayerValue = bayerMatrix[y % bayerSize][x % bayerSize];
            const threshold = (bayerValue / (bayerSize * bayerSize) - 0.5) * ditherFactor;
            
            r = Math.max(0, Math.min(255, r + threshold));
            g = Math.max(0, Math.min(255, g + threshold));
            b = Math.max(0, Math.min(255, b + threshold));
        }

        // Find the closest color from our generated palette
        const newColor = findClosestColor(r, g, b, palette);

        // Update the image data with the new color
        data[i] = newColor[0];
        data[i + 1] = newColor[1];
        data[i + 2] = newColor[2];
        // Alpha channel (data[i + 3]) is left untouched.
    }

    // --- 3. Final Step: Put modified data back ---
    ctx.putImageData(imageData, 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

Image Query Translator for MS Paint is a web-based tool that allows users to pixelate images and reduce their color depth. By adjusting parameters such as the number of colors, block size for pixelation, and dithering options, users can transform their images into a stylized format suitable for retro designs or pixel art. This tool is ideal for graphic designers, digital artists, or anyone needing to simplify images for platform constraints or aesthetic purposes.

Leave a Reply

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