You can edit the below JavaScript code to customize the image tool.
Apply Changes
function processImage(
originalImg,
width = "original",
height = "original",
cropX = "0",
cropY = "0",
cropWidth = "original",
cropHeight = "original",
brightness = "100",
contrast = "100",
saturation = "100",
blur = "0",
grayscale = "0",
invert = "0",
sepia = "0",
hueRotate = "0",
rotate = "0",
flipHorizontal = "0",
flipVertical = "0",
text = "",
textColor = "#ffffff",
textSize = "48"
) {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
// Helper function to safely parse numeric values with a fallback
const parseParam = (val, fallback) => {
const parsed = parseFloat(val);
return !isNaN(parsed) ? parsed : fallback;
};
// 1. Cropping bounds (Source)
const cX = parseParam(cropX, 0);
const cY = parseParam(cropY, 0);
const cW = cropWidth === "original" ? (originalImg.width - cX) : parseParam(cropWidth, originalImg.width - cX);
const cH = cropHeight === "original" ? (originalImg.height - cY) : parseParam(cropHeight, originalImg.height - cY);
// 2. Resizing dimensions (Destination)
const targetWidth = width === "original" ? cW : parseParam(width, cW);
const targetHeight = height === "original" ? cH : parseParam(height, cH);
// 3. Rotation Bounding Box Math
const rot = parseParam(rotate, 0);
const rad = (rot * Math.PI) / 180;
const absCos = Math.abs(Math.cos(rad));
const absSin = Math.abs(Math.sin(rad));
// Calculate canvas size to avoid corners being cut off after rotation
const boundingWidth = targetWidth * absCos + targetHeight * absSin;
const boundingHeight = targetWidth * absSin + targetHeight * absCos;
canvas.width = boundingWidth;
canvas.height = boundingHeight;
// 4. Transform Image (Position, Rotate, and Flip)
const flipH = parseParam(flipHorizontal, 0);
const flipV = parseParam(flipVertical, 0);
ctx.translate(canvas.width / 2, canvas.height / 2);
ctx.rotate(rad);
ctx.scale(flipH ? -1 : 1, flipV ? -1 : 1);
// 5. Apply Artistic & Adjustment Filters
const b = parseParam(brightness, 100);
const c = parseParam(contrast, 100);
const s = parseParam(saturation, 100);
const bl = parseParam(blur, 0);
const g = parseParam(grayscale, 0);
const i = parseParam(invert, 0);
const se = parseParam(sepia, 0);
const hr = parseParam(hueRotate, 0);
ctx.filter = `brightness(${b}%) contrast(${c}%) saturate(${s}%) blur(${bl}px) grayscale(${g}%) invert(${i}%) sepia(${se}%) hue-rotate(${hr}deg)`;
// 6. Draw Image
ctx.drawImage(originalImg, cX, cY, cW, cH, -targetWidth / 2, -targetHeight / 2, targetWidth, targetHeight);
// 7. Apply Watermark / Text Overlay (if specified)
if (typeof text === 'string' && text.trim().length > 0) {
// Reset matrix transforms and filters for crisp, upright text rendering
ctx.setTransform(1, 0, 0, 1, 0, 0);
ctx.filter = 'none';
const tSize = parseParam(textSize, 48);
ctx.font = `bold ${tSize}px sans-serif`;
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
// Add a drop-shadow strictly to the text so it can be read over light or dark areas
ctx.shadowColor = 'rgba(0, 0, 0, 0.7)';
ctx.shadowBlur = 4;
ctx.shadowOffsetX = 2;
ctx.shadowOffsetY = 2;
ctx.fillStyle = textColor;
ctx.fillText(text, canvas.width / 2, canvas.height / 2);
}
return canvas;
}
Apply Changes