You can edit the below JavaScript code to customize the image tool.
function processImage(originalImg, channel = "red") {
const validChannels = ["red", "green", "blue", "alpha"];
// Normalize and validate the 'channel' parameter
let processedChannelName = "red"; // Default value for the channel to be processed
if (typeof channel === 'string') {
const lowerChannel = channel.toLowerCase();
if (validChannels.includes(lowerChannel)) {
processedChannelName = lowerChannel;
} else {
console.warn(`Invalid channel string: "${channel}". Defaulting to "red".`);
// processedChannelName remains "red" as set by its initialization
}
} else if (typeof channel !== 'undefined') {
// This case handles when 'channel' is not a string and was explicitly passed
// (i.e., it's not 'undefined', which would have triggered the default function parameter).
// Examples: null, a number, an object.
console.warn(`Channel parameter must be a string. Received type ${typeof channel} ("${channel}"). Defaulting to "red".`);
// processedChannelName remains "red"
}
// If 'channel' was 'undefined', the default parameter 'red' is used,
// so 'channel' variable inside the function is "red".
// The above 'if/else if' correctly sets processedChannelName to "red" without warnings.
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d', { willReadFrequently: true }); // willReadFrequently for repeated getImageData/putImageData
// Use naturalWidth/Height for intrinsic image dimensions. Fallback to width/height.
const width = originalImg.naturalWidth || originalImg.width;
const height = originalImg.naturalHeight || originalImg.height;
if (width === 0 || height === 0) {
console.error("Image has zero width or height. Make sure the image is loaded and valid before calling processImage.");
// Return a minimal, blank canvas.
canvas.width = 1;
canvas.height = 1;
// Optionally make it transparent or a specific color
ctx.fillStyle = 'rgba(0,0,0,0)'; // Transparent
ctx.fillRect(0,0,1,1);
return canvas;
}
canvas.width = width;
canvas.height = height;
// Draw the original image onto the canvas
try {
ctx.drawImage(originalImg, 0, 0, width, height);
} catch (e) {
console.error("Error drawing image onto canvas: ", e);
// Clear canvas and draw an error message
ctx.clearRect(0, 0, width, height);
ctx.font = "14px Arial";
ctx.fillStyle = "black";
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.fillText("Error drawing original image.", width / 2, height / 2);
return canvas;
}
// Get the pixel data from the canvas. This can fail due to CORS policy.
let imageData;
try {
imageData = ctx.getImageData(0, 0, width, height);
} catch (e) {
console.error("Error getting image data (potentially due to CORS policy): ", e);
// Canvas is tainted. We cannot process pixels. Draw an overlay message on the original image.
ctx.fillStyle = "rgba(0, 0, 0, 0.7)"; // Dark semi-transparent overlay
ctx.fillRect(0, 0, width, height);
ctx.font = "16px Arial"; // Readable font size for the overlay message
ctx.fillStyle = "white";
ctx.textAlign = "center";
ctx.textBaseline = "middle";
const messageLines = ["Failed to process pixels.", "Image may be cross-origin or corrupted."];
const lineHeight = (parseInt(ctx.font, 10) * 1.2) || 20; // Approximate line height
// Calculate starting Y position to center the block of text vertically
const totalTextHeight = messageLines.length * lineHeight;
const startY = height / 2 - totalTextHeight / 2;
for(let i = 0; i < messageLines.length; i++) {
// Position each line's middle at its designated Y coordinate within the block
ctx.fillText(messageLines[i], width / 2, startY + i * lineHeight + lineHeight / 2);
}
return canvas;
}
const data = imageData.data; // This is a Uint8ClampedArray
// Iterate over each pixel and modify according to the selected channel
// Each pixel is 4 bytes (R, G, B, A)
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];
let value; // This will store the intensity of the selected channel
switch (processedChannelName) {
case "red":
value = r;
break;
case "green":
value = g;
break;
case "blue":
value = b;
break;
case "alpha":
value = a;
break;
// No default case needed as processedChannelName is guaranteed to be one of the valid channels.
}
// Set R, G, B components to 'value' to create a grayscale representation of the channel's intensity
data[i] = value; // Red component
data[i + 1] = value; // Green component
data[i + 2] = value; // Blue component
// Handle the alpha component for the output pixel
if (processedChannelName === "alpha") {
// When visualizing the alpha channel, make the pixel fully opaque (alpha = 255)
// so that its grayscale value (derived from the original alpha) is clearly visible.
data[i + 3] = 255;
} else {
// For R, G, B channel visualizations, preserve the original alpha of the pixel.
data[i + 3] = a;
}
}
// Put the modified image data back onto the canvas
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!
The Image Color Channel Separator tool allows users to isolate and view individual color channels of an image, such as red, green, blue, or alpha. This tool can be particularly useful for graphic designers, photographers, and digital artists who want to analyze or manipulate the color composition of images, create special effects, or troubleshoot color-related issues. Users can select a specific channel and obtain a visualization that highlights the intensity of that channel, making it easier to understand the role each color plays in the overall image.