You can edit the below JavaScript code to customize the image tool.
Apply Changes
function processImage(originalImg, hudColor = '#00FF00', addHUD = 1, addGlitch = 1, addScanlines = 1, pixelationSize = 0) {
const width = originalImg.naturalWidth || originalImg.width;
const height = originalImg.naturalHeight || originalImg.height;
const canvas = document.createElement('canvas');
canvas.width = width;
canvas.height = height;
const ctx = canvas.getContext('2d');
// Optional pixelation step for retro robot aesthetic
let pSize = Math.max(1, parseInt(pixelationSize) || 1);
if (pSize > 1) {
const tempCanvas = document.createElement('canvas');
tempCanvas.width = Math.ceil(width / pSize);
tempCanvas.height = Math.ceil(height / pSize);
const tCtx = tempCanvas.getContext('2d');
tCtx.drawImage(originalImg, 0, 0, tempCanvas.width, tempCanvas.height);
ctx.imageSmoothingEnabled = false;
ctx.drawImage(tempCanvas, 0, 0, width, height);
ctx.imageSmoothingEnabled = true;
} else {
ctx.drawImage(originalImg, 0, 0, width, height);
}
// Parse HUD Color (Default Matrix/Terminal-style Neon Green)
let cHex = String(hudColor).trim();
if (/^#[0-9A-Fa-f]{3}$/.test(cHex)) {
cHex = '#' + cHex[1]+cHex[1] + cHex[2]+cHex[2] + cHex[3]+cHex[3];
}
if (!/^#[0-9A-Fa-f]{6}$/.test(cHex)) {
cHex = '#00FF00'; // fallback to green
}
const tint = {
r: parseInt(cHex.substring(1, 3), 16),
g: parseInt(cHex.substring(3, 5), 16),
b: parseInt(cHex.substring(5, 7), 16)
};
// Apply Thermal / Robot Vision Duotone Effect
const imgData = ctx.getImageData(0, 0, width, height);
const data = imgData.data;
for (let i = 0; i < data.length; i += 4) {
let r = data[i];
let g = data[i+1];
let b = data[i+2];
// Map relative luminance with increased contrast
let lum = 0.299 * r + 0.587 * g + 0.114 * b;
lum = ((lum / 255 - 0.5) * 1.5 + 0.5) * 255;
lum = Math.max(0, Math.min(255, lum));
// Create glowing duotone (Dark details to color, Light details to white)
if (lum < 128) {
let f = lum / 128;
data[i] = tint.r * f;
data[i+1] = tint.g * f;
data[i+2] = tint.b * f;
} else {
let f = (lum - 128) / 127;
data[i] = tint.r + (255 - tint.r) * f;
data[i+1] = tint.g + (255 - tint.g) * f;
data[i+2] = tint.b + (255 - tint.b) * f;
}
}
ctx.putImageData(imgData, 0, 0);
// Apply System Glitch / Chromatic Aberration
if (Number(addGlitch) === 1) {
const glitchData = ctx.getImageData(0, 0, width, height);
const gD = glitchData.data;
const offset = Math.floor(width * 0.015) * 4; // Channel horizontal shift
// Shift Red channel right to create chromatic visual artifact
for (let i = gD.length - 4; i >= 0; i -= 4) {
if (i - offset >= 0) {
gD[i] = gD[i - offset];
}
}
ctx.putImageData(glitchData, 0, 0);
// Add visual horizontal splicing / tearing
for (let g = 0; g < 6; g++) {
let sy = Math.floor(Math.random() * height);
let sh = Math.floor(Math.random() * (height * 0.05));
let dx = Math.floor((Math.random() - 0.5) * (width * 0.05));
if (sh > 0) {
ctx.drawImage(canvas, 0, sy, width, sh, dx, sy, width, sh);
}
}
}
// Embed CRT/Digital Display Scanlines
if (Number(addScanlines) === 1) {
ctx.fillStyle = 'rgba(0, 0, 0, 0.4)';
for (let y = 0; y < height; y += 4) {
ctx.fillRect(0, y, width, 2);
}
}
// Paint Target System HUD
if (Number(addHUD) === 1) {
const minDim = Math.min(width, height);
ctx.strokeStyle = cHex;
ctx.fillStyle = cHex;
ctx.shadowColor = cHex;
ctx.shadowBlur = Math.max(2, minDim * 0.015); // Neon glow
ctx.lineWidth = Math.max(1, minDim * 0.006);
const cx = width / 2;
const cy = height / 2;
const boxR = minDim * 0.35;
const cLen = boxR * 0.2;
// Bounding Bracket Frame
ctx.beginPath();
// Top Left
ctx.moveTo(cx - boxR, cy - boxR + cLen);
ctx.lineTo(cx - boxR, cy - boxR);
ctx.lineTo(cx - boxR + cLen, cy - boxR);
// Top Right
ctx.moveTo(cx + boxR - cLen, cy - boxR);
ctx.lineTo(cx + boxR, cy - boxR);
ctx.lineTo(cx + boxR, cy - boxR + cLen);
// Bottom Left
ctx.moveTo(cx - boxR, cy + boxR - cLen);
ctx.lineTo(cx - boxR, cy + boxR);
ctx.lineTo(cx - boxR + cLen, cy + boxR);
// Bottom Right
ctx.moveTo(cx + boxR - cLen, cy + boxR);
ctx.lineTo(cx + boxR, cy + boxR);
ctx.lineTo(cx + boxR, cy + boxR - cLen);
ctx.stroke();
// Central Positioning Crosshair
ctx.beginPath();
let chLen = minDim * 0.04;
ctx.moveTo(cx, cy - chLen * 1.5);
ctx.lineTo(cx, cy - chLen * 0.4);
ctx.moveTo(cx, cy + chLen * 1.5);
ctx.lineTo(cx, cy + chLen * 0.4);
ctx.moveTo(cx - chLen * 1.5, cy);
ctx.lineTo(cx - chLen * 0.4, cy);
ctx.moveTo(cx + chLen * 1.5, cy);
ctx.lineTo(cx + chLen * 0.4, cy);
ctx.stroke();
ctx.beginPath();
ctx.arc(cx, cy, chLen * 0.15, 0, Math.PI * 2);
ctx.fill();
ctx.shadowBlur = 0; // Turn off glow for crisp text reading
let fontSize = Math.max(12, minDim * 0.04);
ctx.font = `bold ${fontSize}px "Courier New", Courier, monospace`;
ctx.textBaseline = 'top';
let tx = cx - boxR;
let ty = cy - boxR - fontSize * 2.2;
// System Core Readouts
ctx.textAlign = 'left';
ctx.fillText(`SYS.ONLINE // MEM: ${(Math.random() * 90 + 10).toFixed(1)}TB`, tx, Math.max(minDim * 0.02, ty - fontSize * 1.2));
ctx.fillText("TARGET: ACQUIRED", tx, Math.max(minDim * 0.02 + fontSize * 1.2, ty));
ctx.textAlign = 'right';
ctx.fillText(`DIST: ${(Math.random() * 70 + 5).toFixed(2)}M`, cx + boxR, cy + boxR + fontSize * 0.5);
// Subprocess Hex Tracking Matrix
ctx.textAlign = 'left';
for (let i = 0; i < 5; i++) {
const memAddress = Math.random().toString(16).substr(2, 6).toUpperCase();
ctx.fillText(`[${i}] 0x${memAddress}`, cx + boxR + minDim * 0.02, cy - boxR + (i * fontSize * 1.4));
}
}
return canvas;
}
Apply Changes