You can edit the below JavaScript code to customize the image tool.
Apply Changes
function processImage(originalImg, mode = "VHS", noiseLevel = 25, rgbShift = 5) {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
// Set canvas dimensions to match the original image
const width = originalImg.width;
const height = originalImg.height;
canvas.width = width;
canvas.height = height;
// Draw the original image onto the canvas
ctx.drawImage(originalImg, 0, 0);
// Get the image data for pixel manipulation
let imgData = ctx.getImageData(0, 0, width, height);
let data = imgData.data;
// Create a temporary canvas/context to hold the original unadulterated pixels
const copyCanvas = document.createElement('canvas');
copyCanvas.width = width;
copyCanvas.height = height;
const copyCtx = copyCanvas.getContext('2d');
copyCtx.drawImage(originalImg, 0, 0);
const copyDataObj = copyCtx.getImageData(0, 0, width, height);
const copyData = copyDataObj.data;
// Parse parameters
const noiseNum = parseInt(noiseLevel, 10);
const shiftNum = parseInt(rgbShift, 10);
const isVHS = mode.toUpperCase() === "VHS";
// Loop through each pixel
for (let y = 0; y < height; y++) {
// VCR Tracking Distortion effect near the bottom of the screen
let offsetBase = 0;
if (isVHS && y > height * 0.88 && y < height * 0.95) {
offsetBase = Math.floor(Math.random() * 15) - 7;
}
for (let x = 0; x < width; x++) {
const index = (y * width + x) * 4;
// Chromatic Aberration (RGB Shift)
let redX = Math.min(width - 1, Math.max(0, x + shiftNum + offsetBase));
let blueX = Math.min(width - 1, Math.max(0, x - shiftNum + offsetBase));
let greenX = Math.min(width - 1, Math.max(0, x + offsetBase));
const rIndex = (y * width + redX) * 4;
const gIndex = (y * width + greenX) * 4;
const bIndex = (y * width + blueX) * 4;
// Apply Shifted Colors
data[index] = copyData[rIndex]; // R
data[index + 1] = copyData[gIndex + 1]; // G
data[index + 2] = copyData[bIndex + 2]; // B
// Alpha remains original (data[index + 3])
// Add Static/Noise
if (noiseNum > 0) {
let noiseVal = (Math.random() - 0.5) * noiseNum * 2;
data[index] = Math.min(255, Math.max(0, data[index] + noiseVal));
data[index + 1] = Math.min(255, Math.max(0, data[index + 1] + noiseVal));
data[index + 2] = Math.min(255, Math.max(0, data[index + 2] + noiseVal));
}
}
}
// Put modulated image data back onto the canvas
ctx.putImageData(imgData, 0, 0);
// Apply Scanlines
ctx.fillStyle = 'rgba(0, 0, 0, 0.25)';
const scanlineThickness = Math.max(1, Math.floor(height / 400));
for (let y = 0; y < height; y += scanlineThickness * 3) {
ctx.fillRect(0, y, width, scanlineThickness);
}
// Apply overall color tint (Greenish for VHS, Bluish for DVD)
ctx.fillStyle = isVHS ? 'rgba(0, 255, 0, 0.04)' : 'rgba(0, 0, 255, 0.04)';
ctx.fillRect(0, 0, width, height);
// Overlay VCR/Player OSD Text (On-Screen Display)
const fontSize = Math.max(14, Math.floor(height * 0.04));
ctx.font = `bold ${fontSize}px "Courier New", Courier, monospace`;
ctx.fillStyle = '#f0f0f0';
// Text Shadows for CRT glow effect
ctx.shadowColor = '#000000';
ctx.shadowBlur = 6;
ctx.shadowOffsetX = 2;
ctx.shadowOffsetY = 2;
const marginX = width * 0.05;
const marginYTop = height * 0.1;
const marginYBottom = height * 0.9;
if (isVHS) {
ctx.fillText('PLAY ►', marginX, marginYTop);
ctx.fillText('SP', width - marginX - (fontSize * 1.5), marginYTop);
ctx.fillText('HIFI VHSRip AUDIO MONO', marginX, marginYBottom);
ctx.fillText('Других Языков', width - marginX - (fontSize * 7.5), marginYBottom);
} else {
ctx.fillText('DVDRip MULTI LANGUAGE', marginX, marginYTop);
ctx.fillText('AUDIO TRACK: 2', marginX, marginYBottom);
ctx.fillText('Других Языков Плеер', width - marginX - (fontSize * 10), marginYBottom);
}
// Reset shadow properties before returning
ctx.shadowBlur = 0;
ctx.shadowOffsetX = 0;
ctx.shadowOffsetY = 0;
return canvas;
}
Apply Changes