You can edit the below JavaScript code to customize the image tool.
async function processImage(originalImg, inscriptionText = 'REC ● 01:23:45', fontSize = 24, fontColor = '#ffcc00', fontName = 'VCR OSD Mono') {
/**
* Dynamically loads a font from Google Fonts.
* @param {string} name - The name of the font.
* @param {string} url - The URL of the font file (e.g., woff2).
* @returns {Promise<boolean>} - A promise that resolves to true if the font is loaded, false otherwise.
*/
async function loadFont(name, url) {
if (document.fonts.check(`1em "${name}"`)) {
return true;
}
try {
const fontFace = new FontFace(name, `url(${url})`);
await fontFace.load();
document.fonts.add(fontFace);
return true;
} catch (error) {
console.error(`Font "${name}" could not be loaded from ${url}.`, error);
return false;
}
}
// 1. Load the special VCR font. Fallback to a generic monospace if it fails.
const fontUrl = 'https://fonts.gstatic.com/s/vcrosdmono/v19/q5uDsoiL2nreB2nK9I4v-22hsvBlZA.woff2';
const fontLoaded = await loadFont(fontName, fontUrl);
if (!fontLoaded) {
fontName = 'monospace'; // Fallback font
}
// 2. Setup canvas
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d', { willReadFrequently: true });
const width = originalImg.naturalWidth;
const height = originalImg.naturalHeight;
canvas.width = width;
canvas.height = height;
// Draw the original image to the canvas
ctx.drawImage(originalImg, 0, 0, width, height);
// Get the pixel data from the canvas
const originalImageData = ctx.getImageData(0, 0, width, height);
const originalData = originalImageData.data;
const vhsImageData = ctx.createImageData(width, height);
const vhsData = vhsImageData.data;
// 3. Apply Chromatic Aberration & Noise in a single pass for efficiency
const aberrationAmount = 4; // in pixels
const noiseAmount = 35; // intensity from 0-255
for (let y = 0; y < height; y++) {
for (let x = 0; x < width; x++) {
const i = (y * width + x) * 4;
// Chromatic Aberration: get R from a left-shifted pixel and B from a right-shifted pixel
const redX = Math.max(0, x - aberrationAmount);
const blueX = Math.min(width - 1, x + aberrationAmount);
const redIndex = (y * width + redX) * 4;
const blueIndex = (y * width + blueX) * 4;
const r = originalData[redIndex];
const g = originalData[i + 1];
const b = originalData[blueIndex + 2];
// Add random noise
const noise = (Math.random() - 0.5) * noiseAmount;
// Assign new pixel values, clamping them between 0 and 255
vhsData[i] = Math.max(0, Math.min(255, r + noise));
vhsData[i + 1] = Math.max(0, Math.min(255, g + noise));
vhsData[i + 2] = Math.max(0, Math.min(255, b + noise));
vhsData[i + 3] = originalData[i + 3]; // Keep original alpha
}
}
// Put the VHS-effect pixel data back onto the canvas
ctx.putImageData(vhsImageData, 0, 0);
// 4. Apply random horizontal glitch/jitter effect
const glitchLines = Math.floor(height * 0.04); // Glitch about 4% of the lines
for (let i = 0; i < glitchLines; i++) {
const y = Math.floor(Math.random() * height);
const h = Math.floor(Math.random() * 10) + 1; // Slice height: 1 to 10 pixels
if (y + h > height) continue;
const xOffset = (Math.random() - 0.5) * (width * 0.1); // Shift up to 10% of width
try {
const sliceData = ctx.getImageData(0, y, width, h);
ctx.putImageData(sliceData, xOffset, y);
} catch (e) {
// This can fail on tainted canvases (e.g., with cross-origin images)
console.warn("Could not apply glitch effect due to canvas security restrictions.");
break; // Stop trying if we hit a security wall
}
}
// 5. Apply semi-transparent scanlines
ctx.fillStyle = 'rgba(10, 10, 10, 0.2)';
for (let i = 0; i < height; i += 3) {
ctx.fillRect(0, i, width, 1.5);
}
// 6. Draw the inscription text
ctx.font = `${fontSize}px "${fontName}"`;
ctx.fillStyle = fontColor;
ctx.textAlign = 'left';
ctx.textBaseline = 'top';
// Add a shadow to make the text pop, mimicking CRT glow
ctx.shadowColor = 'rgba(0, 0, 0, 0.7)';
ctx.shadowBlur = 6;
ctx.shadowOffsetX = 2;
ctx.shadowOffsetY = 2;
const padding = fontSize * 0.8;
ctx.fillText(inscriptionText, padding, padding);
// Reset shadow for any subsequent drawing on this context if it were to be reused
ctx.shadowColor = 'transparent';
ctx.shadowBlur = 0;
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 Effect With Inscription Tool allows users to apply a vintage VHS effect to their images, enhancing them with a nostalgic aesthetic. This tool modifies images by adding chromatic aberration, random noise, horizontal glitches, and semi-transparent scanlines to create an authentic retro video look. Users can also add customizable text inscriptions, such as timestamps or labels, using a specific font reminiscent of old VHS tape recordings. This tool is ideal for creating retro-themed graphics, enhancing video stills, or simply adding a creative touch to images for social media posts, presentations, or personal projects.