You can edit the below JavaScript code to customize the image tool.
Apply Changes
function processImage(originalImg, effectIntensityStr = "1.0", addMoonStr = "true", addClawsStr = "true") {
// Parse constraint-compliant string parameters back into their needed types
const intensity = parseFloat(effectIntensityStr) || 1.0;
const addMoon = String(addMoonStr).toLowerCase() === "true";
const addClaws = String(addClawsStr).toLowerCase() === "true";
const canvas = document.createElement('canvas');
const w = originalImg.width;
const h = originalImg.height;
canvas.width = w;
canvas.height = h;
const ctx = canvas.getContext('2d');
// 0. Base transform: Draw original with heavy dark, contrast and grayscale filters for a rugged "night" look
ctx.filter = `contrast(${100 + intensity * 45}%) brightness(${100 - intensity * 25}%) saturate(45%) grayscale(25%)`;
ctx.drawImage(originalImg, 0, 0, w, h);
ctx.filter = 'none';
// 1. Midnight Blue Tint (Moonlight Phase) - using multiply to darken and cool the tones
ctx.globalCompositeOperation = 'multiply';
ctx.fillStyle = `rgba(16, 28, 52, ${0.6 + intensity * 0.2})`;
ctx.fillRect(0, 0, w, h);
// 2. Generate a procedural Full Moon
if (addMoon) {
ctx.globalCompositeOperation = 'screen';
const r = Math.min(w, h) * 0.12;
const cx = w * 0.85; // Top right positioning
const cy = h * 0.15;
// Ethereal Moon Glow
const moonGlow = ctx.createRadialGradient(cx, cy, r * 0.2, cx, cy, r * 4);
moonGlow.addColorStop(0, 'rgba(180, 210, 255, 0.9)');
moonGlow.addColorStop(1, 'rgba(0, 0, 0, 0)');
ctx.fillStyle = moonGlow;
ctx.beginPath();
ctx.arc(cx, cy, r * 4, 0, Math.PI * 2);
ctx.fill();
// Solid Moon Base
ctx.globalCompositeOperation = 'source-over';
ctx.beginPath();
ctx.arc(cx, cy, r, 0, Math.PI * 2);
ctx.fillStyle = '#E8F0FF';
ctx.fill();
// Moon Texture/Shading (adding simple spherical depth)
const moonShadow = ctx.createRadialGradient(cx - r * 0.3, cy - r * 0.3, r * 0.1, cx, cy, r);
moonShadow.addColorStop(0, 'rgba(255, 255, 255, 0)');
moonShadow.addColorStop(1, 'rgba(20, 30, 50, 0.7)');
ctx.fillStyle = moonShadow;
ctx.fill();
// Moonlight Rays cascading over the image
ctx.globalCompositeOperation = 'screen';
const rays = ctx.createLinearGradient(cx, cy, 0, h);
rays.addColorStop(0, 'rgba(140, 170, 255, 0.25)');
rays.addColorStop(1, 'rgba(0, 0, 0, 0)');
ctx.fillStyle = rays;
ctx.fillRect(0, 0, w, h);
}
// 3. Beast Fur / Grunge Texture Overlay (simulating werewolf skin/hair)
ctx.globalCompositeOperation = 'overlay';
const numStrokes = (w * h) * 0.004 * intensity; // Proportional to resolution
ctx.lineWidth = Math.max(1, w * 0.0015);
for (let i = 0; i < numStrokes; i++) {
const x = Math.random() * w;
const y = Math.random() * h;
const len = Math.random() * (h * 0.06) + (h * 0.01);
const angle = Math.PI / 2 + (Math.random() - 0.5) * 0.7; // Mostly flowing downwards
ctx.beginPath();
ctx.moveTo(x, y);
ctx.lineTo(x + Math.cos(angle) * len, y + Math.sin(angle) * len);
// Mix dark beast fur and some moonlight highlights
ctx.strokeStyle = Math.random() > 0.35 ? 'rgba(10, 10, 10, 0.5)' : 'rgba(220, 230, 255, 0.2)';
ctx.stroke();
}
// 4. Transform bright highlights into Beast Eyes / Demonic Hellish glows
ctx.globalCompositeOperation = 'source-over';
const imgData = ctx.getImageData(0, 0, w, h);
const data = imgData.data;
// We read from an unedited copy of the original to locate original bright spots reliably
const tempCanvas = document.createElement('canvas');
tempCanvas.width = w; tempCanvas.height = h;
const tempCtx = tempCanvas.getContext('2d');
tempCtx.drawImage(originalImg, 0, 0, w, h);
const origData = tempCtx.getImageData(0, 0, w, h).data;
const moonRadius = Math.min(w, h) * 0.12;
const moonCx = w * 0.85;
const moonCy = h * 0.15;
for (let i = 0; i < data.length; i += 4) {
// Exclude the drawn moon area so it remains purely white/blue instead of turning demonic red
const px = (i / 4) % w;
const py = Math.floor((i / 4) / w);
let inMoon = false;
if (addMoon) {
const dist = Math.sqrt((px - moonCx) ** 2 + (py - moonCy) ** 2);
if (dist < moonRadius * 1.5) inMoon = true;
}
if (!inMoon) {
const rOrig = origData[i];
const gOrig = origData[i + 1];
const bOrig = origData[i + 2];
// Calculate natural luminance
const luma = rOrig * 0.299 + gOrig * 0.587 + bOrig * 0.114;
if (luma > 175) {
const factor = Math.min(1, (luma - 175) / 80);
// Color mapping: Overwrite bright spots with fierce red, orange and yellow tones
data[i] = Math.min(255, data[i] + 255 * factor); // Target Max Red
data[i + 1] = Math.min(255, data[i + 1] + 130 * factor); // Target Orange/Yellow
data[i + 2] = Math.floor(data[i + 2] * (1 - factor)); // Eliminate Blues
}
}
}
ctx.putImageData(imgData, 0, 0);
// 5. Theatrical Hunter Vignette (Darkening the edges deeply)
ctx.globalCompositeOperation = 'multiply';
const vig = ctx.createRadialGradient(w / 2, h / 2, Math.min(w, h) * 0.35, w / 2, h / 2, Math.max(w, h) * 0.9);
vig.addColorStop(0, 'rgba(255, 255, 255, 1)');
vig.addColorStop(1, 'rgba(0, 0, 0, 1)');
ctx.fillStyle = vig;
ctx.fillRect(0, 0, w, h);
// 6. Alpha Predator Claw Marks overlay
if (addClaws) {
ctx.globalCompositeOperation = 'source-over';
const cx = w * 0.45;
const cy = h * 0.5;
const clawSize = Math.min(w, h) * 0.35;
ctx.save();
ctx.translate(cx, cy);
ctx.rotate(Math.PI / 5); // Angle the beastly slash diagonally
ctx.shadowColor = 'rgba(255, 20, 20, 1)';
ctx.shadowBlur = w * 0.025;
ctx.fillStyle = 'rgba(160, 0, 0, 0.85)';
// Draw 4 curved gashes
for (let i = 0; i < 4; i++) {
const offset = (i - 1.5) * (clawSize * 0.25);
// Inner claws are typically longer
const lengthScale = (i === 1 || i === 2) ? 1.05 : 0.75;
const currentClawSize = clawSize * lengthScale;
ctx.beginPath();
ctx.moveTo(offset, -currentClawSize);
// Generate a natural slash shape with thick center and sharp tips
ctx.quadraticCurveTo(offset + clawSize * 0.06, 0, offset, currentClawSize);
ctx.quadraticCurveTo(offset - clawSize * 0.04, 0, offset, -currentClawSize);
ctx.fill();
}
ctx.restore();
}
return canvas;
}
Apply Changes