You can edit the below JavaScript code to customize the image tool.
Apply Changes
function processImage(originalImg, commandString = "resize 800 800; filter sepia(50%) contrast(120%); text \"COMMAND TOOL\" 20 40 white 30") {
let canvas = document.createElement('canvas');
canvas.width = originalImg.width;
canvas.height = originalImg.height;
let ctx = canvas.getContext('2d');
ctx.drawImage(originalImg, 0, 0);
if (!commandString || typeof commandString !== 'string') {
return canvas;
}
// Split the input into individual commands using semicolons
const cmds = commandString.split(';').map(c => c.trim()).filter(c => c.length > 0);
for (const cmd of cmds) {
// Regex to split by spaces, but group everything inside double quotes
const parts = cmd.match(/(?:[^\s"]+|"[^"]*")+/g);
if (!parts) continue;
const action = parts[0].toLowerCase();
switch (action) {
case 'resize':
if (parts.length >= 3) {
const mw = parseInt(parts[1], 10);
const mh = parseInt(parts[2], 10);
if (isNaN(mw) || isNaN(mh)) continue;
let nw = canvas.width;
let nh = canvas.height;
// Maintain aspect ratio
const ratio = Math.min(mw / nw, mh / nh);
nw = Math.max(1, Math.round(nw * ratio));
nh = Math.max(1, Math.round(nh * ratio));
const temp = document.createElement('canvas');
temp.width = nw;
temp.height = nh;
temp.getContext('2d').drawImage(canvas, 0, 0, canvas.width, canvas.height, 0, 0, nw, nh);
canvas = temp;
ctx = canvas.getContext('2d');
}
break;
case 'resize!':
if (parts.length >= 3) {
const nw = Math.max(1, parseInt(parts[1], 10));
const nh = Math.max(1, parseInt(parts[2], 10));
if (isNaN(nw) || isNaN(nh)) continue;
const temp = document.createElement('canvas');
temp.width = nw;
temp.height = nh;
temp.getContext('2d').drawImage(canvas, 0, 0, canvas.width, canvas.height, 0, 0, nw, nh);
canvas = temp;
ctx = canvas.getContext('2d');
}
break;
case 'crop':
if (parts.length >= 5) {
const x = parseInt(parts[1], 10);
const y = parseInt(parts[2], 10);
let w = parseInt(parts[3], 10);
let h = parseInt(parts[4], 10);
if (isNaN(x) || isNaN(y) || isNaN(w) || isNaN(h)) continue;
w = Math.max(1, w);
h = Math.max(1, h);
const temp = document.createElement('canvas');
temp.width = w;
temp.height = h;
temp.getContext('2d').drawImage(canvas, x, y, w, h, 0, 0, w, h);
canvas = temp;
ctx = canvas.getContext('2d');
}
break;
case 'filter':
if (parts.length >= 2) {
const filterIdx = cmd.toLowerCase().indexOf('filter');
const filterVal = cmd.substring(filterIdx + 6).trim(); // Extract raw CSS filter string
const tempCanvas = document.createElement('canvas');
tempCanvas.width = canvas.width;
tempCanvas.height = canvas.height;
tempCanvas.getContext('2d').drawImage(canvas, 0, 0);
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.filter = filterVal;
ctx.drawImage(tempCanvas, 0, 0);
ctx.filter = 'none';
}
break;
case 'rotate':
if (parts.length >= 2) {
const degrees = parseFloat(parts[1]);
if (isNaN(degrees)) continue;
const radians = degrees * Math.PI / 180;
const cw = canvas.width;
const ch = canvas.height;
const absCos = Math.abs(Math.cos(radians));
const absSin = Math.abs(Math.sin(radians));
// Keep the bounding box size accurate to avoid cropping
const nw = Math.max(1, Math.ceil(cw * absCos + ch * absSin));
const nh = Math.max(1, Math.ceil(cw * absSin + ch * absCos));
const temp = document.createElement('canvas');
temp.width = nw;
temp.height = nh;
const tCtx = temp.getContext('2d');
tCtx.translate(nw / 2, nh / 2);
tCtx.rotate(radians);
tCtx.drawImage(canvas, -cw / 2, -ch / 2);
canvas = temp;
ctx = canvas.getContext('2d');
}
break;
case 'flip':
if (parts.length >= 2) {
const dir = parts[1].toLowerCase();
const temp = document.createElement('canvas');
temp.width = canvas.width;
temp.height = canvas.height;
temp.getContext('2d').drawImage(canvas, 0, 0);
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.save();
if (dir === 'h' || dir === 'horizontal') {
ctx.scale(-1, 1);
ctx.drawImage(temp, -canvas.width, 0);
} else if (dir === 'v' || dir === 'vertical') {
ctx.scale(1, -1);
ctx.drawImage(temp, 0, -canvas.height);
} else {
ctx.drawImage(temp, 0, 0);
}
ctx.restore();
}
break;
case 'text':
if (parts.length >= 6) {
// Extract exact string without surrounding quotes
const textStr = parts[1].replace(/(^"|"$)/g, "");
const x = parseInt(parts[2], 10);
const y = parseInt(parts[3], 10);
const color = parts[4];
const size = parseInt(parts[5], 10);
if (isNaN(x) || isNaN(y) || isNaN(size)) continue;
ctx.fillStyle = color;
ctx.font = `bold ${size}px sans-serif`;
ctx.textBaseline = 'top';
ctx.fillText(textStr, x, y);
}
break;
case 'rect':
if (parts.length >= 6) {
const x = parseInt(parts[1], 10);
const y = parseInt(parts[2], 10);
const w = parseInt(parts[3], 10);
const h = parseInt(parts[4], 10);
const color = parts[5];
if (isNaN(x) || isNaN(y) || isNaN(w) || isNaN(h)) continue;
ctx.fillStyle = color;
ctx.fillRect(x, y, w, h);
}
break;
case 'circle':
if (parts.length >= 5) {
const x = parseInt(parts[1], 10);
const y = parseInt(parts[2], 10);
const r = parseInt(parts[3], 10);
const color = parts[4];
if (isNaN(x) || isNaN(y) || isNaN(r)) continue;
ctx.fillStyle = color;
ctx.beginPath();
ctx.arc(x, y, r, 0, Math.PI * 2);
ctx.fill();
}
break;
}
}
return canvas;
}
Apply Changes