You can edit the below JavaScript code to customize the image tool.
Apply Changes
function processImage(originalImg, bloomIntensityStr = "1.2", blurRadiusStr = "30", thresholdStr = "140", warmthAlphaStr = "0.6") {
const width = originalImg.width || originalImg.naturalWidth;
const height = originalImg.height || originalImg.naturalHeight;
if (!width || !height) {
return originalImg;
}
const bloomIntensity = parseFloat(bloomIntensityStr);
const blurRadius = parseFloat(blurRadiusStr);
const threshold = parseFloat(thresholdStr);
const warmthAlpha = parseFloat(warmthAlphaStr);
// 1. Setup the main working canvas
const canvas = document.createElement('canvas');
canvas.width = width;
canvas.height = height;
const ctx = canvas.getContext('2d');
// Draw the original image onto the canvas
ctx.drawImage(originalImg, 0, 0);
// 2. Apply Sunrise Color Grade (Warm fiery gradient overlay)
// Create the primary sunrise gradient
const gradient = ctx.createLinearGradient(0, 0, 0, height);
gradient.addColorStop(0.0, '#ff512f'); // Deep sunrise red
gradient.addColorStop(0.5, '#f09819'); // Golden orange
gradient.addColorStop(1.0, '#fff5a8'); // Bright sun yellow
// To prevent tinting transparent areas of the image, we draw the gradient
// onto a separate canvas and mask it using 'destination-in' with the original image.
const gradCanvas = document.createElement('canvas');
gradCanvas.width = width;
gradCanvas.height = height;
const gCtx = gradCanvas.getContext('2d');
gCtx.fillStyle = gradient;
gCtx.fillRect(0, 0, width, height);
gCtx.globalCompositeOperation = 'destination-in';
gCtx.drawImage(canvas, 0, 0);
// Blend the masked gradient into the main image using soft-light
ctx.globalCompositeOperation = 'soft-light';
ctx.globalAlpha = warmthAlpha;
ctx.drawImage(gradCanvas, 0, 0);
// Create a secondary overlay gradient to boost highlights and pink tones
const grad2 = ctx.createLinearGradient(0, 0, 0, height);
grad2.addColorStop(0, '#ff9a9e'); // soft pink
grad2.addColorStop(1, '#fecfef'); // pale glowing pink
const gradCanvas2 = document.createElement('canvas');
gradCanvas2.width = width;
gradCanvas2.height = height;
const gCtx2 = gradCanvas2.getContext('2d');
gCtx2.fillStyle = grad2;
gCtx2.fillRect(0, 0, width, height);
gCtx2.globalCompositeOperation = 'destination-in';
gCtx2.drawImage(canvas, 0, 0);
ctx.globalCompositeOperation = 'overlay';
ctx.globalAlpha = warmthAlpha * 0.6;
ctx.drawImage(gradCanvas2, 0, 0);
// Reset compositing for extraction
ctx.globalCompositeOperation = 'source-over';
ctx.globalAlpha = 1.0;
// 3. Extract Highlights for Bloom
const imgData = ctx.getImageData(0, 0, width, height);
const data = imgData.data;
const bloomData = new ImageData(width, height);
const bData = bloomData.data;
const range = 255 - threshold;
const multiplier = range > 0 ? (255 / range) : 0;
const bloomBoost = 1.3; // Give the highlights an extra pop before blurring
for (let i = 0; i < data.length; i += 4) {
const r = data[i];
const g = data[i+1];
const b = data[i+2];
const a = data[i+3];
// Only evaluate opaque or partially opaque pixels
if (a > 0) {
// Calculate luminance for perceived brightness
const lum = 0.299 * r + 0.587 * g + 0.114 * b;
if (lum > threshold) {
// Smooth falloff scaling for extracted bloom
const scale = ((lum - threshold) * multiplier / 255) * bloomBoost;
bData[i] = r * scale;
bData[i+1] = g * scale;
bData[i+2] = b * scale;
bData[i+3] = a;
} else {
// Pixels below threshold don't contribute to bloom
bData[i] = bData[i+1] = bData[i+2] = bData[i+3] = 0;
}
}
}
// Put extracted bloom highlights onto an off-screen canvas
const extractCanvas = document.createElement('canvas');
extractCanvas.width = width;
extractCanvas.height = height;
const extCtx = extractCanvas.getContext('2d');
extCtx.putImageData(bloomData, 0, 0);
// 4. Blur the Extract Highlights
const blurredCanvas = document.createElement('canvas');
blurredCanvas.width = width;
blurredCanvas.height = height;
const blurCtx = blurredCanvas.getContext('2d');
// Apply the glow logic via canvas filter
blurCtx.filter = `blur(${blurRadius}px)`;
blurCtx.drawImage(extractCanvas, 0, 0);
// 5. Screen-Blend the Bloom Over the Main Image
ctx.globalCompositeOperation = 'screen';
// We loop in case bloomIntensity > 1.0, because globalAlpha maxes out at 1.0
let remainingIntensity = bloomIntensity;
while (remainingIntensity > 0) {
ctx.globalAlpha = Math.min(1.0, remainingIntensity);
ctx.drawImage(blurredCanvas, 0, 0);
remainingIntensity -= 1.0;
}
// Reset alpha and compositing mode before returning
ctx.globalAlpha = 1.0;
ctx.globalCompositeOperation = 'source-over';
return canvas;
}
Apply Changes