You can edit the below JavaScript code to customize the image tool.
Apply Changes
/**
* A versatile image editing controller that applies various operations to an image.
* This function can perform operations like adjusting brightness, contrast, saturation,
* applying grayscale, sepia, or invert filters, blurring, rotating, flipping,
* cropping, and resizing.
*
* @param {HTMLImageElement} originalImg The original image element to process. Must be a loaded image.
* @param {string} [operation='none'] The editing operation to perform. Possible values:
* 'brightness', 'contrast', 'saturation', 'grayscale', 'invert', 'sepia', 'blur',
* 'rotate', 'flip', 'crop', 'resize'.
* @param {number|string} [value1=0] The first parameter for the operation. Its meaning depends on the operation:
* - 'brightness', 'contrast', 'saturation': A number from -100 to 100.
* - 'blur': The blur radius in pixels (number).
* - 'rotate': The rotation angle in degrees (number).
* - 'flip': The flip direction, 'horizontal' or 'vertical' (string). Defaults to 'horizontal'.
* - 'crop': The x-coordinate of the top-left corner (number).
* - 'resize': The new width. If 0 or less, aspect ratio is maintained based on value2 (number).
* @param {number} [value2=0] The second parameter for the operation. Its meaning depends on the operation:
* - 'crop': The y-coordinate of the top-left corner (number).
* - 'resize': The new height. If 0 or less, aspect ratio is maintained based on value1 (number).
* @param {number} [value3=0] The third parameter for the operation.
* - 'crop': The width of the crop area. If 0 or less, it crops to the image's right edge (number).
* @param {number} [value4=0] The fourth parameter for the operation.
* - 'crop': The height of the crop area. If 0 or less, it crops to the image's bottom edge (number).
* @returns {Promise<HTMLCanvasElement>} A promise that resolves with a new canvas element containing the processed image.
*/
async function processImage(originalImg, operation = 'none', value1 = 0, value2 = 0, value3 = 0, value4 = 0) {
// Ensure the image is fully loaded before processing.
if (!originalImg.complete || originalImg.naturalWidth === 0) {
await new Promise((resolve, reject) => {
originalImg.onload = resolve;
originalImg.onerror = reject;
});
}
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
const w = originalImg.naturalWidth;
const h = originalImg.naturalHeight;
canvas.width = w;
canvas.height = h;
switch (operation.toLowerCase()) {
case 'brightness':
case 'contrast':
case 'saturation':
{
const amount = 100 + Math.max(-100, Math.min(100, Number(value1)));
ctx.filter = `${operation.toLowerCase()}(${amount}%)`;
ctx.drawImage(originalImg, 0, 0, w, h);
break;
}
case 'grayscale':
case 'invert':
case 'sepia':
{
ctx.filter = `${operation.toLowerCase()}(100%)`;
ctx.drawImage(originalImg, 0, 0, w, h);
break;
}
case 'blur':
{
const radius = Math.max(0, Number(value1));
ctx.filter = `blur(${radius}px)`;
ctx.drawImage(originalImg, 0, 0, w, h);
break;
}
case 'rotate':
{
const angle = Number(value1);
const angleRad = angle * Math.PI / 180;
const cos = Math.cos(angleRad);
const sin = Math.sin(angleRad);
const newWidth = Math.ceil(Math.abs(w * cos) + Math.abs(h * sin));
const newHeight = Math.ceil(Math.abs(w * sin) + Math.abs(h * cos));
canvas.width = newWidth;
canvas.height = newHeight;
ctx.translate(newWidth / 2, newHeight / 2);
ctx.rotate(angleRad);
ctx.drawImage(originalImg, -w / 2, -h / 2, w, h);
break;
}
case 'flip':
{
const direction = String(value1).toLowerCase();
if (direction === 'vertical') {
ctx.translate(0, h);
ctx.scale(1, -1);
} else { // 'horizontal' or any other value defaults to horizontal
ctx.translate(w, 0);
ctx.scale(-1, 1);
}
ctx.drawImage(originalImg, 0, 0, w, h);
break;
}
case 'crop':
{
const x = Number(value1);
const y = Number(value2);
const cropW = Number(value3);
const cropH = Number(value4);
const finalX = Math.max(0, x);
const finalY = Math.max(0, y);
const finalW = cropW > 0 ? Math.min(cropW, w - finalX) : w - finalX;
const finalH = cropH > 0 ? Math.min(cropH, h - finalY) : h - finalY;
if (finalW > 0 && finalH > 0) {
canvas.width = finalW;
canvas.height = finalH;
ctx.drawImage(originalImg, finalX, finalY, finalW, finalH, 0, 0, finalW, finalH);
} else {
canvas.width = 1;
canvas.height = 1; // Return a 1x1 empty canvas for invalid crop
}
break;
}
case 'resize':
{
let newWidth = Number(value1);
let newHeight = Number(value2);
if (newWidth <= 0 && newHeight <= 0) {
newWidth = w;
newHeight = h;
} else if (newWidth > 0 && newHeight <= 0) {
newHeight = Math.round(h * (newWidth / w));
} else if (newHeight > 0 && newWidth <= 0) {
newWidth = Math.round(w * (newHeight / h));
}
canvas.width = newWidth;
canvas.height = newHeight;
ctx.drawImage(originalImg, 0, 0, newWidth, newHeight);
break;
}
case 'none':
default:
ctx.drawImage(originalImg, 0, 0, w, h);
break;
}
return canvas;
}
Apply Changes