You can edit the below JavaScript code to customize the image tool.
function processImage(
originalImg,
labelText = "AUTHENTICATED",
fontSize = 20,
fontColor = "rgba(255, 255, 255, 0.8)",
fontFamily = "Arial",
position = "bottom-right",
padding = 10,
startTimeText = "",
endTimeText = ""
) {
// 1. Create a canvas
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
// 2. Set canvas dimensions
// Use naturalWidth/Height if available, fallback to width/height.
// This handles cases where originalImg might be an <img> tag scaled by CSS.
// For a pure JS Image object, width/height are usually natural dimensions once loaded.
const imgWidth = originalImg.naturalWidth || originalImg.width;
const imgHeight = originalImg.naturalHeight || originalImg.height;
canvas.width = imgWidth;
canvas.height = imgHeight;
// If image dimensions are zero (e.g., image not loaded correctly),
// we might return an empty canvas or log a warning.
if (canvas.width === 0 || canvas.height === 0) {
console.warn("Image dimensions are zero. The image might not be loaded correctly. Returning an empty canvas.");
// The returned canvas will be 0x0 or have the invalid dimensions.
// Downstream code should handle this if it's a possibility.
return canvas;
}
// 3. Draw the original image onto the canvas
ctx.drawImage(originalImg, 0, 0, canvas.width, canvas.height);
// 4. Prepare the time-related text based on startTimeText and endTimeText parameters
let timeInfoText;
// Ensure parameters are strings before calling trim, use empty string as fallback for null/undefined.
const stt = (typeof startTimeText === 'string' && startTimeText !== null) ? startTimeText.trim() : "";
const ett = (typeof endTimeText === 'string' && endTimeText !== null) ? endTimeText.trim() : "";
if (stt !== "" && ett !== "") {
timeInfoText = `Period: ${stt} - ${ett}`;
} else if (stt !== "") {
timeInfoText = `From: ${stt}`;
} else if (ett !== "") {
timeInfoText = `Until: ${ett}`;
} else {
// Default to current timestamp if no period is specified
const now = new Date();
const year = now.getFullYear();
const month = String(now.getMonth() + 1).padStart(2, '0'); // Months are 0-indexed
const day = String(now.getDate()).padStart(2, '0');
const hours = String(now.getHours()).padStart(2, '0');
const minutes = String(now.getMinutes()).padStart(2, '0');
const seconds = String(now.getSeconds()).padStart(2, '0');
timeInfoText = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
}
// 5. Prepare lines of text to be drawn
const lines = [];
const lt = (typeof labelText === 'string' && labelText !== null) ? labelText.trim() : "";
if (lt !== "") {
lines.push(lt);
}
lines.push(timeInfoText);
// 6. Set font properties
// Ensure fontSize and padding are numbers; use defaults if conversion fails or invalid.
let numFontSize = Number(fontSize);
if (isNaN(numFontSize) || numFontSize <= 0) {
numFontSize = 20; // Fallback to default if invalid
}
let numPadding = Number(padding);
if (isNaN(numPadding) || numPadding < 0) {
numPadding = 10; // Fallback to default if invalid
}
const safeFontFamily = (typeof fontFamily === 'string' && fontFamily.trim() !== "") ? fontFamily : 'Arial';
ctx.font = `${numFontSize}px ${safeFontFamily}`;
ctx.fillStyle = (typeof fontColor === 'string') ? fontColor : "rgba(255, 255, 255, 0.8)";
// 7. Calculate text position and draw text lines
let x, y;
// Approximate line height. For more precision, advanced text metrics would be needed.
const lineHeight = numFontSize * 1.2;
// Normalize position string (e.g., 'Bottom-Right' -> 'bottom-right')
const normalizedPosition = (typeof position === 'string') ? position.toLowerCase().trim() : 'bottom-right';
switch (normalizedPosition) {
case "bottom-left":
ctx.textAlign = 'left';
ctx.textBaseline = 'bottom'; // Text's bottom edge aligns with y
x = numPadding;
y = canvas.height - numPadding;
// Draw lines from bottom up
for (let i = 0; i < lines.length; i++) {
ctx.fillText(lines[lines.length - 1 - i], x, y - i * lineHeight);
}
break;
case "top-right":
ctx.textAlign = 'right';
ctx.textBaseline = 'top'; // Text's top edge aligns with y
x = canvas.width - numPadding;
y = numPadding;
// Draw lines from top down
for (let i = 0; i < lines.length; i++) {
ctx.fillText(lines[i], x, y + i * lineHeight);
}
break;
case "top-left":
ctx.textAlign = 'left';
ctx.textBaseline = 'top';
x = numPadding;
y = numPadding;
for (let i = 0; i < lines.length; i++) {
ctx.fillText(lines[i], x, y + i * lineHeight);
}
break;
case "center":
ctx.textAlign = 'center';
ctx.textBaseline = 'middle'; // Text's vertical center aligns with y
x = canvas.width / 2;
// Calculate the Y for the center of the entire text block
const totalTextHeightFromCenters = (lines.length - 1) * lineHeight;
// startY will be the y-coordinate for the center of the first line
const startY = (canvas.height / 2) - (totalTextHeightFromCenters / 2);
for (let i = 0; i < lines.length; i++) {
ctx.fillText(lines[i], x, startY + i * lineHeight);
}
break;
case "bottom-right":
default:
// If position is unrecognized, default to bottom-right
if (normalizedPosition !== "bottom-right") {
console.warn(`Invalid position "${position}" specified, defaulting to bottom-right.`);
}
ctx.textAlign = 'right';
ctx.textBaseline = 'bottom';
x = canvas.width - numPadding;
y = canvas.height - numPadding;
for (let i = 0; i < lines.length; i++) {
ctx.fillText(lines[lines.length - 1 - i], x, y - i * lineHeight);
}
break;
}
// 8. Return the modified canvas
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 Time Period Authentication Creator is a tool that allows users to authenticate images by adding a customizable label and time period information directly onto the image. This is particularly useful for documenting events, verifying timestamps for photographs, or labeling artwork with exhibiting times. Users can specify the position, font size, color, and typeface of the text, ensuring the watermark complements the image’s aesthetics while providing necessary authentication details. Typical use cases include professional photography, event documentation, and creating digital proof of ownership.