You can edit the below JavaScript code to customize the image tool.
Apply Changes
function processImage(originalImg, hudColor = "#00FF00", showScanline = 1, textOverlay = "TARGET ACQUIRED", filterMode = 0) {
const canvas = document.createElement('canvas');
const w = originalImg.width;
const h = originalImg.height;
canvas.width = w;
canvas.height = h;
const ctx = canvas.getContext('2d');
// --- 1. Apply Movie Scanner Filter Modes ---
if (filterMode === 1) {
// Mode 1: Night Vision / Infrared Amplified View
ctx.drawImage(originalImg, 0, 0, w, h);
const imgData = ctx.getImageData(0, 0, w, h);
const data = imgData.data;
for (let i = 0; i < data.length; i += 4) {
// Calculate luminance and boost
let lum = 0.299 * data[i] + 0.587 * data[i+1] + 0.114 * data[i+2];
let bright = Math.min(255, lum * 1.5);
data[i] = bright;
data[i+1] = bright;
data[i+2] = bright;
}
ctx.putImageData(imgData, 0, 0);
// Subtly tint with HUD color using multiply
ctx.globalCompositeOperation = 'multiply';
ctx.fillStyle = hudColor;
ctx.fillRect(0, 0, w, h);
ctx.globalCompositeOperation = 'source-over';
} else if (filterMode === 2) {
// Mode 2: Edge Detection / Laser Scanner View
const tCanvas = document.createElement('canvas');
tCanvas.width = w; tCanvas.height = h;
const tCtx = tCanvas.getContext('2d');
// Fast pseudo-edge detection using difference blend mode
tCtx.drawImage(originalImg, 0, 0, w, h);
tCtx.globalCompositeOperation = 'difference';
tCtx.drawImage(originalImg, 2, 2, w, h);
ctx.fillStyle = 'black';
ctx.fillRect(0, 0, w, h);
ctx.globalCompositeOperation = 'lighter';
ctx.drawImage(tCanvas, 0, 0, w, h);
ctx.globalCompositeOperation = 'source-over';
// Convert colored edges to bright monochromatic edges
const imgData = ctx.getImageData(0, 0, w, h);
const data = imgData.data;
for (let i = 0; i < data.length; i += 4) {
let val = Math.min(255, (data[i] + data[i+1] + data[i+2]));
data[i] = val;
data[i+1] = val;
data[i+2] = val;
}
ctx.putImageData(imgData, 0, 0);
// Tint edges with the scanner HUD color
ctx.globalCompositeOperation = 'multiply';
ctx.fillStyle = hudColor;
ctx.fillRect(0, 0, w, h);
ctx.globalCompositeOperation = 'source-over';
} else {
// Mode 0: Standard Cinematic View
ctx.drawImage(originalImg, 0, 0, w, h);
}
// --- 2. Screen Vignette ---
const gradient = ctx.createRadialGradient(w/2, h/2, Math.min(w,h)*0.3, w/2, h/2, Math.max(w,h)*0.8);
gradient.addColorStop(0, 'rgba(0,0,0,0)');
gradient.addColorStop(1, 'rgba(0,0,0,0.6)');
ctx.fillStyle = gradient;
ctx.fillRect(0, 0, w, h);
// --- 3. Draw Scanner HUD (Heads-Up Display) ---
ctx.strokeStyle = hudColor;
ctx.fillStyle = hudColor;
ctx.shadowColor = hudColor;
ctx.shadowBlur = Math.max(5, Math.min(w, h) * 0.01);
const baseLineWidth = Math.max(1.5, Math.min(w, h) * 0.005);
ctx.lineWidth = baseLineWidth;
const m = Math.min(w, h) * 0.05; // Margins
const bSize = Math.min(w, h) * 0.15; // Viewfinder bracket sizes
// A. Viewfinder Corner Brackets
ctx.beginPath();
// Top Left
ctx.moveTo(m, m + bSize); ctx.lineTo(m, m); ctx.lineTo(m + bSize, m);
// Top Right
ctx.moveTo(w - m - bSize, m); ctx.lineTo(w - m, m); ctx.lineTo(w - m, m + bSize);
// Bottom Right
ctx.moveTo(w - m, h - m - bSize); ctx.lineTo(w - m, h - m); ctx.lineTo(w - m - bSize, h - m);
// Bottom Left
ctx.moveTo(m + bSize, h - m); ctx.lineTo(m, h - m); ctx.lineTo(m, h - m - bSize);
ctx.stroke();
// B. Center Target Crosshair & Circle
const cx = w / 2;
const cy = h / 2;
const cSize = Math.min(w, h) * 0.08;
ctx.beginPath();
ctx.moveTo(cx - cSize, cy); ctx.lineTo(cx - cSize * 0.3, cy);
ctx.moveTo(cx + cSize * 0.3, cy); ctx.lineTo(cx + cSize, cy);
ctx.moveTo(cx, cy - cSize); ctx.lineTo(cx, cy - cSize * 0.3);
ctx.moveTo(cx, cy + cSize * 0.3); ctx.lineTo(cx, cy + cSize);
ctx.stroke();
ctx.beginPath();
ctx.arc(cx, cy, cSize * 1.5, 0, Math.PI * 2);
ctx.setLineDash([Math.max(4, w*0.01), Math.max(8, w*0.02)]);
ctx.stroke();
ctx.setLineDash([]); // Reset line dash
// Inner Target Dot
ctx.beginPath();
ctx.arc(cx, cy, baseLineWidth, 0, Math.PI * 2);
ctx.fill();
// C. Sci-Fi UI Overlay Text Readings
ctx.shadowBlur = 0; // Turn off glow for crisp and legible text reading
const fontSize = Math.max(12, Math.min(w, h) * 0.03);
ctx.font = `${fontSize}px "Courier New", Courier, monospace`;
ctx.textAlign = "left";
ctx.textBaseline = "middle";
ctx.fillText("SYS.ON // SCANNER.FINDER.MOVIES", m + 10, m + bSize + fontSize);
ctx.fillText(`STATUS: [ ${textOverlay} ]`, m + 10, m + bSize + fontSize * 2.5);
// Simulate Random Coordinates
ctx.fillText(`LAT: ${ (Math.random() * 90).toFixed(4) } N`, m + 10, h - m - bSize - fontSize * 2);
ctx.fillText(`LON: ${ (Math.random() * 180).toFixed(4) } W`, m + 10, h - m - bSize - fontSize * 0.5);
// D. Right-Side Scanner Activity Bars
const numBars = 10;
const barW = Math.min(w, w * 0.1);
const barH = h * 0.02;
const barStartX = w - m - barW;
let barY = h / 2 - (numBars * barH * 1.5) / 2;
for(let i=0; i<numBars; i++) {
const fillW = barW * (0.2 + Math.random() * 0.8);
ctx.globalAlpha = 0.3;
ctx.fillRect(barStartX, barY, barW, barH);
ctx.globalAlpha = 0.9;
ctx.fillRect(barStartX, barY, fillW, barH);
barY += barH * 1.5;
}
ctx.globalAlpha = 1.0;
// E. Glowing Recording / REC Indicator
const recRadius = Math.max(6, Math.min(w, h) * 0.015);
ctx.fillStyle = "#FF0000";
ctx.beginPath();
ctx.arc(w - m - recRadius * 4 - fontSize * 2, m + recRadius, recRadius, 0, Math.PI * 2);
ctx.fill();
ctx.fillStyle = "#FFFFFF";
ctx.font = `bold ${fontSize}px Arial, sans-serif`;
ctx.textAlign = "right";
ctx.fillText("REC", w - m, m + recRadius);
// --- 4. Render Laser Scanline Beam ---
if (showScanline === 1) {
const scanY = h * 0.45; // Fixed somewhat towards the center to simulate ongoing scanning
ctx.shadowBlur = 15;
ctx.shadowColor = hudColor;
ctx.fillStyle = hudColor;
ctx.strokeStyle = hudColor;
// Beam Halo/Glow
ctx.globalAlpha = 0.2;
ctx.fillRect(0, scanY - h * 0.02, w, h * 0.04);
// Intense bright center line
ctx.globalAlpha = 0.9;
ctx.beginPath();
ctx.moveTo(0, scanY);
ctx.lineTo(w, scanY);
ctx.lineWidth = baseLineWidth * 2;
ctx.stroke();
ctx.globalAlpha = 1.0;
ctx.shadowBlur = 0;
}
return canvas;
}
Apply Changes