You can edit the below JavaScript code to customize the image tool.
Apply Changes
async function processImage(originalImg, iterations = "8", decaySeverity = "1.0") {
const loops = parseInt(iterations, 10) || 8;
const severity = parseFloat(decaySeverity) || 1.0;
const canvas = document.createElement('canvas');
const width = originalImg.width;
const height = originalImg.height;
canvas.width = width;
canvas.height = height;
// willReadFrequently optimizes the canvas for heavy getImageData/putImageData operations
const ctx = canvas.getContext('2d', { willReadFrequently: true });
ctx.drawImage(originalImg, 0, 0);
// Helper to simulate progressive generation loss via low-quality JPEG compression
const applyJPEGGenerationLoss = (quality) => {
return new Promise((resolve) => {
const img = new Image();
img.onload = () => {
ctx.clearRect(0, 0, width, height);
ctx.drawImage(img, 0, 0);
resolve();
};
img.onerror = resolve; // fail gracefully and continue
img.src = canvas.toDataURL('image/jpeg', Math.max(0.01, Math.min(quality, 1.0)));
});
};
for (let i = 0; i < loops; i++) {
// Calculate progressive deterioration factors
let progress = (i + 1) / loops;
let currentSeverity = progress * severity;
// 1. Pixel Manipulation: Chromatic Aberration, Posterization, and Noise
let imgData = ctx.getImageData(0, 0, width, height);
let data = imgData.data;
let levels = Math.max(2, 32 - Math.floor(28 * currentSeverity));
let factor = 255 / (levels - 1);
let maxShift = Math.floor(15 * currentSeverity);
let shiftX = Math.floor((Math.random() - 0.5) * 2 * maxShift);
// Copy original channel data to prevent localized cascading
let temp = new Uint8ClampedArray(data);
for (let y = 0; y < height; y++) {
for (let x = 0; x < width; x++) {
let idx = (y * width + x) * 4;
// Shift Red channel to simulate chromatic aberration
let sx = Math.min(Math.max(x + shiftX, 0), width - 1);
let sIdx = (y * width + sx) * 4;
let r = temp[sIdx]; // Shifted Red
let g = temp[idx + 1]; // Normal Green
let b = temp[idx + 2]; // Normal Blue
// Dynamic digital noise
let noise = (Math.random() - 0.5) * 60 * currentSeverity;
// Bit-crushing / Posterization to decay structural color gradations
data[idx] = Math.round((r + noise) / factor) * factor;
data[idx + 1] = Math.round((g + noise) / factor) * factor;
data[idx + 2] = Math.round((b + noise) / factor) * factor;
}
}
ctx.putImageData(imgData, 0, 0);
// 2. Spatial Glitching / Memory Corruption Blocks
let numBlocks = Math.floor(20 * currentSeverity);
for (let b = 0; b < numBlocks; b++) {
let bw = Math.random() * (width / 4);
let bh = Math.random() * (height / 4);
let bx = Math.random() * width;
let by = Math.random() * height;
let dx = bx + (Math.random() - 0.5) * 60 * currentSeverity;
let dy = by + (Math.random() - 0.5) * 60 * currentSeverity;
ctx.drawImage(canvas, bx, by, bw, bh, dx, dy, bw, bh);
}
// 3. Bleed/Blur effect to melt semantics and destroy edges
let tempCanvas = document.createElement('canvas');
tempCanvas.width = width;
tempCanvas.height = height;
tempCanvas.getContext('2d').drawImage(canvas, 0, 0);
ctx.clearRect(0, 0, width, height);
let blurAmount = Math.random() * 3 * currentSeverity;
let saturationAmount = Math.max(0, 100 - (50 * currentSeverity));
ctx.filter = `blur(${blurAmount}px) saturate(${saturationAmount}%)`;
ctx.drawImage(tempCanvas, 0, 0);
ctx.filter = 'none';
// 4. Generation Loss via continuous aggressive JPEG compression
let quality = Math.max(0.01, 0.9 - (0.85 * currentSeverity));
await applyJPEGGenerationLoss(quality);
}
return canvas;
}
Apply Changes