You can edit the below JavaScript code to customize the image tool.
Apply Changes
function processImage(originalImg, blockSize = 20, blockGap = 2, warmth = 25, vignetteStrength = 0.6, backgroundColor = '#202020') {
// Validate and sanitize parameters
let s_blockSize = parseInt(String(blockSize), 10);
s_blockSize = isNaN(s_blockSize) ? 20 : Math.max(1, s_blockSize);
let s_blockGap = parseInt(String(blockGap), 10);
s_blockGap = isNaN(s_blockGap) ? 2 : Math.max(0, s_blockGap);
// Ensure actual block drawn is at least 1x1 pixel, and gap isn't too large
if (s_blockGap >= s_blockSize) {
s_blockGap = Math.max(0, s_blockSize - 1);
}
let s_warmth = parseFloat(String(warmth));
s_warmth = isNaN(s_warmth) ? 25 : Math.max(0, Math.min(100, s_warmth));
let s_vignetteStrength = parseFloat(String(vignetteStrength));
s_vignetteStrength = isNaN(s_vignetteStrength) ? 0.6 : Math.max(0, Math.min(1, s_vignetteStrength));
const s_backgroundColor = typeof backgroundColor === 'string' ? backgroundColor : '#202020';
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
canvas.width = originalImg.width;
canvas.height = originalImg.height;
// Fill background (visible in gaps)
ctx.fillStyle = s_backgroundColor;
ctx.fillRect(0, 0, canvas.width, canvas.height);
// Use an offscreen canvas for reading pixel data from original image
const offscreenCanvas = document.createElement('canvas');
offscreenCanvas.width = canvas.width;
offscreenCanvas.height = canvas.height;
const offscreenCtx = offscreenCanvas.getContext('2d', { willReadFrequently: true });
offscreenCtx.drawImage(originalImg, 0, 0);
const actualBlockDrawableWidth = s_blockSize - s_blockGap;
const actualBlockDrawableHeight = s_blockSize - s_blockGap;
for (let y = 0; y < canvas.height; y += s_blockSize) {
for (let x = 0; x < canvas.width; x += s_blockSize) {
const currentBlockDataWidth = Math.min(s_blockSize, canvas.width - x);
const currentBlockDataHeight = Math.min(s_blockSize, canvas.height - y);
if (currentBlockDataWidth <= 0 || currentBlockDataHeight <= 0) continue;
let imageData;
try {
imageData = offscreenCtx.getImageData(x, y, currentBlockDataWidth, currentBlockDataHeight);
} catch (e) {
console.error("Image Orchestra Seating Filter: Error getting image data for block at (" + x + "," + y +"). This might be due to cross-origin restrictions.", e);
continue;
}
const data = imageData.data;
let r_sum = 0, g_sum = 0, b_sum = 0;
const pixelCount = currentBlockDataWidth * currentBlockDataHeight;
if (pixelCount === 0) continue;
for (let i = 0; i < data.length; i += 4) {
r_sum += data[i];
g_sum += data[i + 1];
b_sum += data[i + 2];
}
let avgR = Math.floor(r_sum / pixelCount);
let avgG = Math.floor(g_sum / pixelCount);
let avgB = Math.floor(b_sum / pixelCount);
// Apply warmth
avgR = Math.min(255, avgR + s_warmth);
avgB = Math.max(0, avgB - s_warmth);
ctx.fillStyle = `rgb(${avgR},${avgG},${avgB})`;
const drawX = x + s_blockGap / 2;
const drawY = y + s_blockGap / 2;
let finalDrawWidth = Math.min(actualBlockDrawableWidth, currentBlockDataWidth - s_blockGap);
let finalDrawHeight = Math.min(actualBlockDrawableHeight, currentBlockDataHeight - s_blockGap);
finalDrawWidth = Math.max(0, finalDrawWidth);
finalDrawHeight = Math.max(0, finalDrawHeight);
if (finalDrawWidth > 0 && finalDrawHeight > 0) {
ctx.fillRect(drawX, drawY, finalDrawWidth, finalDrawHeight);
}
}
}
// Apply vignette
if (s_vignetteStrength > 0) {
const centerX = canvas.width / 2;
const centerY = canvas.height / 2;
const outerRadius = Math.sqrt(centerX * centerX + centerY * centerY);
const innerRadiusSpreadFactor = 0.2;
const innerRadius = Math.min(canvas.width, canvas.height) * innerRadiusSpreadFactor;
const gradient = ctx.createRadialGradient(centerX, centerY, innerRadius, centerX, centerY, outerRadius);
gradient.addColorStop(0, 'rgba(0,0,0,0)');
gradient.addColorStop(1, `rgba(0,0,0,${s_vignetteStrength})`);
ctx.globalCompositeOperation = 'source-over';
ctx.fillStyle = gradient;
ctx.fillRect(0, 0, canvas.width, canvas.height);
}
return canvas;
}
Apply Changes