You can edit the below JavaScript code to customize the image tool.
function processImage(originalImg, silhouetteColor = "black", alphaThresholdInput = 0) {
// Ensure alphaThreshold is a valid number between 0 and 255
let alphaThreshold = Number(alphaThresholdInput);
// Check if 'alphaThreshold' became NaN (e.g. from Number("text_value")) or if input was non-finite
if (isNaN(alphaThreshold) || !isFinite(alphaThreshold)) {
alphaThreshold = 0; // Default to 0 if an invalid value was provided
}
// Clamp the threshold to the valid 0-255 range and ensure it's an integer
alphaThreshold = Math.max(0, Math.min(255, Math.floor(alphaThreshold)));
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
// Use naturalWidth/Height for the intrinsic dimensions of the image
const imgWidth = originalImg.naturalWidth;
const imgHeight = originalImg.naturalHeight;
canvas.width = imgWidth;
canvas.height = imgHeight;
// Handle cases where image dimensions are invalid (e.g., image not loaded or is 0x0)
if (imgWidth === 0 || imgHeight === 0) {
// Make canvas somewhat visible and show an error message if it was 0x0
canvas.width = canvas.width === 0 ? 200 : canvas.width;
canvas.height = canvas.height === 0 ? 50 : canvas.height;
ctx.font = "14px Arial";
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.fillStyle = "red"; // Error text color
ctx.fillText("Invalid image or not loaded.", canvas.width / 2, canvas.height / 2, canvas.width * 0.9);
return canvas;
}
// Draw the original image onto the canvas. This is required to access its pixel data.
ctx.drawImage(originalImg, 0, 0, imgWidth, imgHeight);
let imageData;
try {
imageData = ctx.getImageData(0, 0, imgWidth, imgHeight);
} catch (e) {
// This error can occur if the image is cross-origin ("tainted" canvas)
// or other rarer issues with getImageData.
console.error("Error an processImage getting ImageData:", e);
// Clear the canvas (it might have the original image drawn) and show an error message.
ctx.clearRect(0, 0, imgWidth, imgHeight);
let msg = "Error: Could not process image pixels.";
if (e.name === 'SecurityError') {
msg = "Error: Cross-origin image. Cannot access pixels.";
}
// Adjust font size for the error message to fit the canvas
let fontSize = 16;
if (imgWidth < 300 || imgHeight < 100) {
fontSize = 12;
}
if (imgWidth < 150 || imgHeight < 50) {
fontSize = Math.max(8, Math.floor(Math.min(imgWidth, imgHeight) / 10));
}
ctx.font = `${fontSize}px Arial`;
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.fillStyle = "red";
ctx.fillText(msg, imgWidth / 2, imgHeight / 2, imgWidth * 0.95); // Use most of the canvas width for the text
return canvas;
}
const data = imageData.data; // This is a Uint8ClampedArray containing pixel data (R,G,B,A, R,G,B,A, ...)
// Determine the RGB components of the silhouette color.
// A temporary 1x1 canvas is used to parse the `silhouetteColor` string (e.g., "red", "#FF0000", "rgb(255,0,0)")
// into its R, G, B components. This is a robust way to handle various CSS color formats.
const tempCanvas = document.createElement('canvas');
tempCanvas.width = 1;
tempCanvas.height = 1;
const tempCtx = tempCanvas.getContext('2d', {
// Hint for optimization for contexts that are read from frequently.
// For a single 1x1 pixel read, its impact is minimal but doesn't hurt.
willReadFrequently: true
});
tempCtx.fillStyle = silhouetteColor; // Apply the user-specified color string
tempCtx.fillRect(0, 0, 1, 1); // Draw a 1x1 rectangle filled with this color
const colorData = tempCtx.getImageData(0, 0, 1, 1).data; // Read the RGBA value of that pixel
const rSilhouette = colorData[0];
const gSilhouette = colorData[1];
const bSilhouette = colorData[2];
// Note: The alpha component of the silhouetteColor (colorData[3]) is intentionally ignored.
// Silhouettes are typically rendered as fully opaque.
// Iterate over each pixel in the image data. Each pixel consists of 4 bytes (R, G, B, A).
for (let i = 0; i < data.length; i += 4) {
const alpha = data[i + 3]; // Get the alpha value of the current pixel from the original image
// If the original pixel's alpha value is greater than the specified threshold,
// it's considered part of the "shape" and should be colored with the silhouette color.
if (alpha > alphaThreshold) {
data[i] = rSilhouette; // Set Red component to silhouette color's Red
data[i + 1] = gSilhouette; // Set Green component to silhouette color's Green
data[i + 2] = bSilhouette; // Set Blue component to silhouette color's Blue
data[i + 3] = 255; // Set Alpha to fully opaque (255) for the silhouette
} else {
// If the pixel's alpha is not above the threshold, it's considered "background"
// or transparent enough, so make this pixel fully transparent.
data[i + 3] = 0; // Set Alpha to 0 (fully transparent)
}
}
// 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 Silhouette Filter is a tool that allows users to convert images into stylized silhouettes. By applying a specified silhouette color and an alpha transparency threshold, users can transform images in a way that highlights their shapes while removing background details. This functionality can be useful for creating artistic representations, designing graphics, or generating icons and logos that require a simplified and clear outline of forms.