You can edit the below JavaScript code to customize the image tool.
Apply Changes
function processImage(originalImg, blastIntensity = 0.6, redBoost = 1.2, vignetteStrength = 0.8, centerX = 0.5, centerY = 0.5) {
// Read original width and height
const w = originalImg.width || originalImg.naturalWidth;
const h = originalImg.height || originalImg.naturalHeight;
if (!w || !h) {
console.error("Invalid image dimensions.");
return null;
}
// Determine explosion origin (focal point)
const cx = w * Math.max(0, Math.min(1, centerX));
const cy = h * Math.max(0, Math.min(1, centerY));
// Create a temporary canvas for color grading
const tempCanvas = document.createElement('canvas');
tempCanvas.width = w;
tempCanvas.height = h;
const tCtx = tempCanvas.getContext('2d');
// Draw initial image
tCtx.drawImage(originalImg, 0, 0, w, h);
// Get pixel data for Devil's Color Grading
const imgData = tCtx.getImageData(0, 0, w, h);
const data = imgData.data;
// Apply high contrast curve parameters
const contrast = 1.5;
const intercept = 128 * (1 - contrast);
for (let i = 0; i < data.length; i += 4) {
let r = data[i];
let g = data[i + 1];
let b = data[i + 2];
// Apply contrast
r = r * contrast + intercept;
g = g * contrast + intercept;
b = b * contrast + intercept;
// Mix with luma to unify the color base while keeping some variation
let luma = 0.299 * r + 0.587 * g + 0.114 * b;
r = r * 0.4 + luma * 0.6;
g = g * 0.4 + luma * 0.6;
b = b * 0.4 + luma * 0.6;
// Shift colors into Hellfire properties (Heavy Red, moderate Orange/Yellow, minimal Blue)
let fireR = r * 1.5 * redBoost;
let fireG = g * 0.6 * redBoost;
let fireB = b * 0.2;
// Clamp values to safe 8-bit color space
data[i] = Math.min(255, Math.max(0, fireR));
data[i + 1] = Math.min(255, Math.max(0, fireG));
data[i + 2] = Math.min(255, Math.max(0, fireB));
}
tCtx.putImageData(imgData, 0, 0);
// Prepare Final Canvas
const canvas = document.createElement('canvas');
canvas.width = w;
canvas.height = h;
const ctx = canvas.getContext('2d');
// Solid dark background to prevent transparency bleeding
ctx.fillStyle = '#000';
ctx.fillRect(0, 0, w, h);
// Draw base tinted image
ctx.globalAlpha = 1.0;
ctx.drawImage(tempCanvas, 0, 0);
// "Blast" Effect - Radial Zoom Blur via Scale Iterations
const steps = 40;
// 'screen' mode creates a luminous fiery bloom around bright patches
ctx.globalCompositeOperation = 'screen';
for (let i = 1; i <= steps; i++) {
// Scale gradually outwards depending on user's blastIntensity
const scale = 1 + (i / steps) * blastIntensity;
ctx.save();
// Modulate alpha with a sine wave to create 'concussive' shockwave ridges instead of a smooth blur
ctx.globalAlpha = 0.03 + Math.sin(i * 1.2) * 0.015;
ctx.translate(cx, cy);
ctx.scale(scale, scale);
ctx.drawImage(tempCanvas, -cx, -cy);
ctx.restore();
}
// Overlay the tinted original again gently to preserve central focus
ctx.globalCompositeOperation = 'source-over';
ctx.globalAlpha = 0.6;
ctx.drawImage(tempCanvas, 0, 0);
// Apply dark, sinister vignette towards the edges
if (vignetteStrength > 0) {
ctx.globalCompositeOperation = 'multiply';
ctx.globalAlpha = Math.min(1, vignetteStrength);
const maxRadius = Math.max(w, h);
const gradient = ctx.createRadialGradient(
cx, cy, Math.min(w, h) * 0.1,
cx, cy, maxRadius * 0.75
);
gradient.addColorStop(0, 'rgba(255,255,255,1)'); // Center stays fully bright
gradient.addColorStop(1, 'rgba(0,0,0,1)'); // Edges darken out
ctx.fillStyle = gradient;
ctx.fillRect(0, 0, w, h);
}
// Reset alpha and blend mode
ctx.globalAlpha = 1.0;
ctx.globalCompositeOperation = 'source-over';
return canvas;
}
Apply Changes