You can edit the below JavaScript code to customize the image tool.
async function processImage(originalImg, noiseAmount = 0.15, scanlineIntensity = 0.2, channelShift = 4, glitchIntensity = 0.3, osdText = "REC ● 01:23:45") {
// This function applies a VHS-style filter to an image.
// The "Video and Audio" parts of the tool name are interpreted as providing
// the aesthetic of a VHS recording, as processing actual video/audio is
// beyond the scope of a function that takes a single image object.
// Step 1: Dynamically load a retro-looking font for the OSD text.
// We use the FontFace API to load 'VT323' from Google Fonts.
// The function is async to wait for the font to be available.
try {
const font = new FontFace('VT323', 'url(https://fonts.gstatic.com/s/vt323/v17/loBsmMgpcv_OC_2gfC_am0QN.woff2)');
await font.load();
document.fonts.add(font);
} catch (e) {
console.error("VHS filter font could not be loaded. Using a fallback font.", e);
}
// Step 2: Set up the canvas.
const canvas = document.createElement('canvas');
// Using { willReadFrequently: true } can improve performance for repeated getImageData calls.
const ctx = canvas.getContext('2d', {
willReadFrequently: true
});
const w = originalImg.naturalWidth;
const h = originalImg.naturalHeight;
canvas.width = w;
canvas.height = h;
// Step 3: Draw the original image with a slight blur to mimic lower resolution.
ctx.filter = 'blur(0.6px)';
ctx.drawImage(originalImg, 0, 0, w, h);
ctx.filter = 'none';
// Step 4: Apply Chromatic Aberration & Color Bleeding effect.
// This is done by shifting the Red and Blue color channels horizontally.
const imageData = ctx.getImageData(0, 0, w, h);
const data = imageData.data;
const originalData = new Uint8ClampedArray(data); // Work on a copy
for (let i = 0; i < data.length; i += 4) {
// Red channel: read from a pixel 'channelShift' to the left
const rIndex = i - (channelShift * 4);
if (rIndex >= 0) {
data[i] = originalData[rIndex];
}
// Green channel: remains in place (no change)
// Blue channel: read from a pixel 'channelShift' to the right
const bIndex = i + 2 + (channelShift * 4);
if (bIndex < originalData.length) {
data[i + 2] = originalData[bIndex];
}
}
ctx.putImageData(imageData, 0, 0);
// Step 5: Add analog noise.
const noiseData = ctx.getImageData(0, 0, w, h);
const pixels = noiseData.data;
for (let i = 0; i < pixels.length; i += 4) {
// Add a random value to R, G, and B channels
for (let j = 0; j < 3; j++) {
const noise = (Math.random() - 0.5) * 255 * noiseAmount;
pixels[i + j] = Math.max(0, Math.min(255, pixels[i + j] + noise));
}
}
ctx.putImageData(noiseData, 0, 0);
// Step 6: Emulate CRT scanlines.
ctx.fillStyle = `rgba(0, 0, 0, ${scanlineIntensity})`;
for (let i = 0; i < h; i += 4) { // Draw 2px dark lines with 2px gap
ctx.fillRect(0, i, w, 2);
}
// Step 7: Simulate tape tracking errors (horizontal glitches).
if (glitchIntensity > 0) {
const numGlitches = Math.floor(glitchIntensity * (h / 30));
for (let i = 0; i < numGlitches; i++) {
const y = Math.random() * h;
const glitchHeight = Math.random() * 30 + 1;
const xOffset = (Math.random() - 0.5) * w * 0.1;
if (y + glitchHeight > h) continue;
// Grab a slice of the canvas and draw it back on with a horizontal offset
ctx.drawImage(canvas,
0, y, w, glitchHeight,
xOffset, y, w, glitchHeight
);
}
}
// Step 8: Apply a vignette effect to darken the edges.
const grd = ctx.createRadialGradient(w / 2, h / 2, Math.min(w, h) / 3, w / 2, h / 2, Math.max(w, h));
grd.addColorStop(0, 'rgba(0,0,0,0)');
grd.addColorStop(1, 'rgba(0,0,0,0.4)');
ctx.fillStyle = grd;
ctx.fillRect(0, 0, w, h);
// Step 9: Add the On-Screen Display (OSD) text if provided.
if (osdText && osdText.trim() !== "") {
const fontSize = Math.min(w, h) * 0.04;
ctx.font = `${fontSize}px VT323, 'Courier New', monospace`;
ctx.fillStyle = 'rgba(255, 255, 220, 0.7)';
ctx.textBaseline = 'top';
ctx.textAlign = 'left';
// Add a shadow for better contrast against the busy background
ctx.shadowColor = 'black';
ctx.shadowBlur = 6;
ctx.shadowOffsetX = 2;
ctx.shadowOffsetY = 2;
const padding = w * 0.025;
ctx.fillText(osdText, padding, padding);
}
// Step 10: Return the final canvas element.
return canvas;
}
Free Image Tool Creator
Can't find the image tool you're looking for? Create one based on your own needs now!
The Image VHS Filter Video And Audio Converter is a tool designed to transform images into a retro VHS-style aesthetic, reminiscent of old analog video recordings. It applies a variety of effects such as chromatic aberration, analog noise, scanlines, and tape tracking glitches to create a distinctive vintage look. Users can also add custom on-screen display (OSD) text to their images. This tool is useful for adding nostalgic vibes to photos, enhancing social media posts, creating unique digital artwork, or simply exploring retro visuals.