Please bookmark this page to avoid losing your image tool!

Image Black And White To Color High-Resolution 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 a black and white image to a colorized, high-resolution version.
 * This is achieved through a two-step process:
 * 1. Colorization: Applies a "split-toning" effect, tinting the shadows and highlights
 *    of the image with user-specified colors.
 * 2. High-Resolution: Upscales the image by a given factor and applies a sharpening
 *    filter to enhance details and make the result look crisp.
 *
 * @param {Image} originalImg The original Image object to process.
 * @param {number} scale The factor by which to increase the image resolution (e.g., a value of 2 makes it twice as large). Defaults to 2.
 * @param {string} shadowsColor A CSS hex color string for the color to apply to the dark areas of the image. Defaults to navy blue ('#000080').
 * @param {string} highlightsColor A CSS hex color string for the color to apply to the light areas of the image. Defaults to light yellow ('#FFFFE0').
 * @param {number} sharpness A value from 0 (no sharpening) to 1 (full sharpening) controlling the intensity of the sharpening effect. Defaults to 0.5.
 * @returns {HTMLCanvasElement} A canvas element containing the processed image.
 */
function processImage(originalImg, scale = 2, shadowsColor = '#000080', highlightsColor = '#FFFFE0', sharpness = 0.5) {

    /**
     * Helper function to convert a CSS hex color string to an {r, g, b} object.
     * @param {string} hex The hex color string (e.g., '#FF0000').
     * @returns {{r: number, g: number, b: number}|null} An object with r, g, b values or null if invalid.
     */
    const hexToRgb = (hex) => {
        const shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
        hex = hex.replace(shorthandRegex, (m, r, g, b) => r + r + g + g + b + b);
        const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
        return result ? {
            r: parseInt(result[1], 16),
            g: parseInt(result[2], 16),
            b: parseInt(result[3], 16)
        } : null;
    };

    const shadowRgb = hexToRgb(shadowsColor);
    const highlightRgb = hexToRgb(highlightsColor);

    if (!shadowRgb || !highlightRgb) {
        console.error("Invalid hex color format. Please use formats like #FFF or #FFFFFF.");
        const fallbackCanvas = document.createElement('canvas');
        fallbackCanvas.width = originalImg.width;
        fallbackCanvas.height = originalImg.height;
        fallbackCanvas.getContext('2d').drawImage(originalImg, 0, 0);
        return fallbackCanvas;
    }

    // Step 1: Apply split-toning colorization
    const colorCanvas = document.createElement('canvas');
    colorCanvas.width = originalImg.width;
    colorCanvas.height = originalImg.height;
    const colorCtx = colorCanvas.getContext('2d');
    colorCtx.drawImage(originalImg, 0, 0);

    const imageData = colorCtx.getImageData(0, 0, colorCanvas.width, colorCanvas.height);
    const data = imageData.data;

    for (let i = 0; i < data.length; i += 4) {
        const r = data[i];
        const g = data[i + 1];
        const b = data[i + 2];
        
        // Calculate grayscale luminance
        const gray = 0.299 * r + 0.587 * g + 0.114 * b;
        const t = gray / 255; // Interpolation factor (0 for black, 1 for white)

        // Linearly interpolate between the shadow and highlight colors
        data[i] = shadowRgb.r * (1 - t) + highlightRgb.r * t;
        data[i + 1] = shadowRgb.g * (1 - t) + highlightRgb.g * t;
        data[i + 2] = shadowRgb.b * (1 - t) + highlightRgb.b * t;
    }
    colorCtx.putImageData(imageData, 0, 0);

    // Step 2: Upscale the colorized image
    const finalWidth = originalImg.width * scale;
    const finalHeight = originalImg.height * scale;
    const finalCanvas = document.createElement('canvas');
    finalCanvas.width = finalWidth;
    finalCanvas.height = finalHeight;
    const finalCtx = finalCanvas.getContext('2d', { willReadFrequently: true });
    
    // Use the browser's high-quality scaling
    finalCtx.imageSmoothingEnabled = true;
    finalCtx.imageSmoothingQuality = 'high';
    finalCtx.drawImage(colorCanvas, 0, 0, finalWidth, finalHeight);

    // Step 3: Apply sharpening filter
    const clampedSharpness = Math.max(0, Math.min(1, sharpness)); // Clamp between 0 and 1
    if (clampedSharpness > 0) {
        const upscaledImageData = finalCtx.getImageData(0, 0, finalWidth, finalHeight);
        const sourceData = new Uint8ClampedArray(upscaledImageData.data);
        const destData = upscaledImageData.data;

        // Simple 3x3 sharpening kernel
        const kernel = [0, -1, 0, -1, 5, -1, 0, -1, 0];
        const halfSide = 1;

        for (let y = 0; y < finalHeight; y++) {
            for (let x = 0; x < finalWidth; x++) {
                const dstOff = (y * finalWidth + x) * 4;
                let r = 0, g = 0, b = 0;

                // Apply convolution kernel
                for (let cy = 0; cy < 3; cy++) {
                    for (let cx = 0; cx < 3; cx++) {
                        const scy = y + cy - halfSide;
                        const scx = x + cx - halfSide;

                        if (scy >= 0 && scy < finalHeight && scx >= 0 && scx < finalWidth) {
                            const srcOff = (scy * finalWidth + scx) * 4;
                            const wt = kernel[cy * 3 + cx];
                            r += sourceData[srcOff] * wt;
                            g += sourceData[srcOff + 1] * wt;
                            b += sourceData[srcOff + 2] * wt;
                        }
                    }
                }
                
                // Blend the sharpened pixel with the original based on sharpness
                const originalR = sourceData[dstOff];
                const originalG = sourceData[dstOff + 1];
                const originalB = sourceData[dstOff + 2];
                
                destData[dstOff]     = originalR * (1 - clampedSharpness) + r * clampedSharpness;
                destData[dstOff + 1] = originalG * (1 - clampedSharpness) + g * clampedSharpness;
                destData[dstOff + 2] = originalB * (1 - clampedSharpness) + b * clampedSharpness;
            }
        }
        finalCtx.putImageData(upscaledImageData, 0, 0);
    }

    return finalCanvas;
}

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 Black and White to Color High-Resolution Converter is a tool that allows users to transform black and white images into vibrant, colorized versions with enhanced resolution. It employs a two-step process: first, it applies a split-toning colorization effect, allowing users to specify colors for shadows and highlights, and second, it upscales the image while sharpening the details for a crisp appearance. This tool is ideal for artists looking to add color to historical photos, creators wanting to enhance monochrome images for design purposes, or anyone seeking to modernize old black and white pictures.

Leave a Reply

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