You can edit the below JavaScript code to customize the image tool.
Apply Changes
function processImage(originalImg, backgroundColor = "#DDDDDD", shadowColor = "rgba(0,0,0,0.3)", highlightColor = "rgba(255,255,255,0.3)", inkColor = "#333333", depth = 1, desaturation = 0.0) {
const canvas = document.createElement('canvas');
// Ensure originalImg has dimensions.
// Assumes originalImg is a loaded HTMLImageElement, HTMLCanvasElement, or similar with width/height properties.
const imgWidth = originalImg.width || 0;
const imgHeight = originalImg.height || 0;
canvas.width = imgWidth;
canvas.height = imgHeight;
// If dimensions are 0, no point proceeding. Return empty canvas.
if (imgWidth === 0 || imgHeight === 0) {
// console.warn("Image Letterpress Filter: originalImg has no dimensions or is not loaded.");
return canvas;
}
const ctx = canvas.getContext('2d');
// Ensure numeric parameters are numbers
depth = Number(depth);
desaturation = Number(desaturation);
// Helper to create a monochrome version of an image using its alpha channel
const createMonochromeVersion = (sourceImg, color) => {
const mCanvas = document.createElement('canvas');
mCanvas.width = sourceImg.width;
mCanvas.height = sourceImg.height;
const mCtx = mCanvas.getContext('2d');
mCtx.drawImage(sourceImg, 0, 0);
mCtx.globalCompositeOperation = 'source-in';
mCtx.fillStyle = color;
mCtx.fillRect(0, 0, mCanvas.width, mCanvas.height);
// Reset composite operation for cleanliness, though mCtx is local
mCtx.globalCompositeOperation = 'source-over';
return mCanvas; // Returns a new canvas with the monochrome image
};
// Helper to create a desaturated version of an image
const createDesaturatedVersion = (sourceImg, amount) => { // amount 0 to 1
const dCanvas = document.createElement('canvas');
dCanvas.width = sourceImg.width;
dCanvas.height = sourceImg.height;
const dCtx = dCanvas.getContext('2d');
const clampedAmount = Math.min(1, Math.max(0, amount)); // Clamp between 0 and 1
if (clampedAmount > 0) {
dCtx.filter = `grayscale(${clampedAmount * 100}%)`;
}
dCtx.drawImage(sourceImg, 0, 0);
if (clampedAmount > 0) {
dCtx.filter = 'none'; // Reset filter
}
return dCanvas; // Returns a new canvas with the desaturated image
};
// 1. Fill background (the "paper")
ctx.fillStyle = backgroundColor;
ctx.fillRect(0, 0, canvas.width, canvas.height);
// 2. Draw Highlight Layer (simulates light catching the top-left edge of the depression)
// Check if highlightColor is a valid color string (not empty or "none")
if (typeof highlightColor === 'string' && highlightColor.trim() !== "" && highlightColor.toLowerCase() !== "none") {
const highlightLayer = createMonochromeVersion(originalImg, highlightColor);
ctx.drawImage(highlightLayer, -depth, -depth);
}
// 3. Draw Shadow Layer (simulates shadow on the bottom-right edge of the depression)
if (typeof shadowColor === 'string' && shadowColor.trim() !== "" && shadowColor.toLowerCase() !== "none") {
const shadowLayer = createMonochromeVersion(originalImg, shadowColor);
ctx.drawImage(shadowLayer, depth, depth);
}
// 4. Prepare and Draw the main "Ink" Layer
let inkImageToDraw;
// If inkColor is specified, use it to colorize the image
if (typeof inkColor === 'string' && inkColor.trim() !== "" && inkColor.toLowerCase() !== "none") {
inkImageToDraw = createMonochromeVersion(originalImg, inkColor);
} else { // Otherwise, use original image colors, possibly desaturated
if (desaturation > 0) {
inkImageToDraw = createDesaturatedVersion(originalImg, desaturation);
} else {
inkImageToDraw = originalImg; // Use original image directly
}
}
// Draw the final ink layer at the base of the "impression"
ctx.drawImage(inkImageToDraw, 0, 0);
return canvas;
}
Apply Changes