Please bookmark this page to avoid losing your image tool!

Image CMYK Color Display Tool

(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.
async function processImage(originalImg) {
    const width = originalImg.width;
    const height = originalImg.height;

    if (width === 0 || height === 0) {
        const emptyCanvas = document.createElement('canvas');
        emptyCanvas.width = 100;
        emptyCanvas.height = 30;
        const emptyCtx = emptyCanvas.getContext('2d');
        emptyCtx.fillStyle = 'white';
        emptyCtx.fillRect(0, 0, emptyCanvas.width, emptyCanvas.height);
        emptyCtx.fillStyle = 'black';
        emptyCtx.font = '12px Arial';
        emptyCtx.textAlign = 'center';
        emptyCtx.fillText("Empty image", 50, 20);
        return emptyCanvas;
    }

    // 1. Create a working canvas to get image data
    const workingCanvas = document.createElement('canvas');
    workingCanvas.width = width;
    workingCanvas.height = height;
    // Add { willReadFrequently: true } for potential performance optimization if supported/needed.
    const workingCtx = workingCanvas.getContext('2d', { willReadFrequently: true }); 
    workingCtx.drawImage(originalImg, 0, 0);
    
    let imageData;
    try {
        imageData = workingCtx.getImageData(0, 0, width, height);
    } catch (e) {
        console.error("Error getting image data:", e);
        const errorCanvas = document.createElement('canvas');
        errorCanvas.width = Math.max(300, width * 2); // Adjust size to be somewhat useful
        errorCanvas.height = 100;
        const errCtx = errorCanvas.getContext('2d');
        errCtx.fillStyle = '#f0f0f0';
        errCtx.fillRect(0, 0, errorCanvas.width, errorCanvas.height);
        errCtx.fillStyle = 'red';
        errCtx.font = 'bold 16px Arial';
        errCtx.textAlign = 'center';
        errCtx.fillText("Error: Could not process image.", errorCanvas.width / 2, 35);
        errCtx.font = '14px Arial';
        errCtx.fillStyle = 'black';
        errCtx.fillText("This may be due to cross-origin restrictions if the image is hosted on another server.", errorCanvas.width / 2, 65);
        return errorCanvas;
    }
    const data = imageData.data;

    // 2. Prepare ImageData for each CMYK channel
    const cImageData = workingCtx.createImageData(width, height);
    const mImageData = workingCtx.createImageData(width, height);
    const yImageData = workingCtx.createImageData(width, height);
    const kImageData = workingCtx.createImageData(width, height);

    const cData = cImageData.data;
    const mData = mImageData.data;
    const yData = yImageData.data;
    const kData = kImageData.data;

    // 3. Iterate through pixels and convert RGB to CMYK
    for (let i = 0; i < data.length; i += 4) {
        let r_srgb = data[i];
        let g_srgb = data[i + 1];
        let b_srgb = data[i + 2];
        let alpha = data[i + 3];

        let r = r_srgb / 255;
        let g = g_srgb / 255;
        let b = b_srgb / 255;

        let k_val = 1 - Math.max(r, g, b);
        let c_val, m_val, y_val;

        if (Math.abs(1 - k_val) < 1e-9) { // k_val is essentially 1 (i.e. RGB is black)
            c_val = 0;
            m_val = 0;
            y_val = 0;
        } else {
            // The (1-k_val) denominator will not be zero here
            c_val = (1 - r - k_val) / (1 - k_val);
            m_val = (1 - g - k_val) / (1 - k_val);
            y_val = (1 - b - k_val) / (1 - k_val);
        }
        
        // Clamp CMYK values to [0, 1] range to safeguard against precision errors
        c_val = Math.max(0, Math.min(1, c_val));
        m_val = Math.max(0, Math.min(1, m_val));
        y_val = Math.max(0, Math.min(1, y_val));
        k_val = Math.max(0, Math.min(1, k_val)); // k_val should already be in [0,1]

        // Convert CMYK (0-1) to grayscale intensity (0-255)
        // Convention: 0 = black (max ink), 255 = white (no ink)
        // This shows where ink would be applied density.
        let c_gray = Math.round((1 - c_val) * 255);
        let m_gray = Math.round((1 - m_val) * 255);
        let y_gray = Math.round((1 - y_val) * 255);
        let k_gray = Math.round((1 - k_val) * 255);

        cData[i] = c_gray; cData[i + 1] = c_gray; cData[i + 2] = c_gray; cData[i + 3] = alpha;
        mData[i] = m_gray; mData[i + 1] = m_gray; mData[i + 2] = m_gray; mData[i + 3] = alpha;
        yData[i] = y_gray; yData[i + 1] = y_gray; yData[i + 2] = y_gray; yData[i + 3] = alpha;
        kData[i] = k_gray; kData[i + 1] = k_gray; kData[i + 2] = k_gray; kData[i + 3] = alpha;
    }

    // 4. Create the output canvas layout
    const padding = 15;
    const labelHeight = 25; 
    const fontConfig = '14px Arial';
    const labelColor = '#333333';
    const borderColor = '#AAAAAA';
    const backgroundColor = '#F0F0F0';

    const totalWidth = (width * 2) + (padding * 3);
    const totalHeight = (height * 2) + (padding * 3) + (labelHeight * 2);

    const outputCanvas = document.createElement('canvas');
    outputCanvas.width = totalWidth;
    outputCanvas.height = totalHeight;
    const outCtx = outputCanvas.getContext('2d');

    outCtx.fillStyle = backgroundColor;
    outCtx.fillRect(0, 0, totalWidth, totalHeight);
    
    const drawChannel = (channelImageData, label, col, row) => {
        // Position calculation for current channel block (label + image)
        const blockX = padding + col * (width + padding);
        const blockY_label = padding + row * (height + padding + labelHeight);
        const blockY_image = blockY_label + labelHeight;

        // Draw label
        outCtx.fillStyle = labelColor;
        outCtx.font = fontConfig;
        outCtx.textAlign = 'center';
        outCtx.textBaseline = 'middle';
        outCtx.fillText(label, blockX + width / 2, blockY_label + labelHeight / 2);

        // Draw image data for the channel
        outCtx.putImageData(channelImageData, blockX, blockY_image);

        // Draw border around the channel image
        outCtx.strokeStyle = borderColor;
        outCtx.lineWidth = 1;
        // Adjust by -0.5 for crisp 1px lines
        outCtx.strokeRect(blockX - 0.5, blockY_image - 0.5, width + 1, height + 1);
    };

    drawChannel(cImageData, "Cyan (C)", 0, 0);
    drawChannel(mImageData, "Magenta (M)", 1, 0);
    drawChannel(yImageData, "Yellow (Y)", 0, 1);
    drawChannel(kImageData, "Key/Black (K)", 1, 1);
    
    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 CMYK Color Display Tool allows users to upload an image and visually analyze its color composition in the CMYK color model. It converts the image from RGB to CMYK, providing separate grayscale displays for Cyan, Magenta, Yellow, and Key (Black) channels. This tool is particularly useful for graphic designers, printers, and artists who need to understand how colors are represented in printing, ensuring accurate color reproduction and effective color management in print design processes.

Leave a Reply

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