You can edit the below JavaScript code to customize the image tool.
Apply Changes
function processImage(
originalImg,
scanLineSpacing = 4,
scanLineOpacity = 0.1,
scanLineThickness = 1,
noiseIntensity = 0.1,
noiseStrength = 30,
glitchStripeFrequency = 0.05,
glitchStripeHeight = 15,
glitchMaxHorizontalOffset = 20
) {
const width = originalImg.width;
const height = originalImg.height;
// 1. Create a base canvas, draw the original image on it.
const baseCanvas = document.createElement('canvas');
baseCanvas.width = width;
baseCanvas.height = height;
const baseCtx = baseCanvas.getContext('2d');
baseCtx.drawImage(originalImg, 0, 0, width, height);
// 2. Apply noise to the baseCanvas.
if (noiseIntensity > 0 && noiseStrength > 0) {
const imageData = baseCtx.getImageData(0, 0, width, height);
const pixels = imageData.data; // pixels is a Uint8ClampedArray [r,g,b,a, r,g,b,a, ...]
for (let i = 0; i < pixels.length; i += 4) {
if (Math.random() < noiseIntensity) {
// Add random noise to R, G, B channels
const rOffset = (Math.random() * 2 - 1) * noiseStrength;
const gOffset = (Math.random() * 2 - 1) * noiseStrength;
const bOffset = (Math.random() * 2 - 1) * noiseStrength;
pixels[i] = Math.max(0, Math.min(255, pixels[i] + rOffset));
pixels[i + 1] = Math.max(0, Math.min(255, pixels[i + 1] + gOffset));
pixels[i + 2] = Math.max(0, Math.min(255, pixels[i + 2] + bOffset));
// Alpha (pixels[i+3]) remains unchanged
}
}
baseCtx.putImageData(imageData, 0, 0);
}
// Now baseCanvas contains the noisy version of the image.
// 3. Create the output canvas (this will be the returned canvas).
const outputCanvas = document.createElement('canvas');
outputCanvas.width = width;
outputCanvas.height = height;
const outputCtx = outputCanvas.getContext('2d');
// 4. Copy the noisy image (baseCanvas) to outputCanvas. This will be the base for glitches.
outputCtx.drawImage(baseCanvas, 0, 0, width, height);
// 5. Apply Glitch Effect to outputCanvas, sourcing stripes from baseCanvas.
if (glitchStripeFrequency > 0 && glitchMaxHorizontalOffset > 0 && glitchStripeHeight > 0) {
for (let y = 0; y < height; y += glitchStripeHeight) {
if (Math.random() < glitchStripeFrequency) {
const currentStripeActualHeight = Math.min(glitchStripeHeight, height - y);
const horizontalOffset = (Math.random() * 2 - 1) * glitchMaxHorizontalOffset;
// Draw a shifted stripe from baseCanvas (noisy, unglitched) onto outputCanvas
outputCtx.drawImage(
baseCanvas, // Source: the noisy, but pre-glitch image
0, // sourceX
y, // sourceY
width, // sourceWidth
currentStripeActualHeight, // sourceHeight
horizontalOffset, // destinationX (shifted)
y, // destinationY
width, // destinationWidth
currentStripeActualHeight // destinationHeight
);
}
}
}
// 6. Apply Scan Lines to outputCanvas (on top of noisy and glitched image).
if (scanLineOpacity > 0 && scanLineSpacing > 0 && scanLineThickness > 0) {
outputCtx.fillStyle = `rgba(0, 0, 0, ${scanLineOpacity})`;
for (let y = 0; y < height; y += scanLineSpacing) {
outputCtx.fillRect(0, y, width, scanLineThickness);
}
}
// 7. Return the final outputCanvas.
return outputCanvas;
}
Apply Changes