You can edit the below JavaScript code to customize the image tool.
Apply Changes
function processImage(originalImg, subtitleText = "TRANSLATED: HELLO WORLD", vhsIntensity = 30, colorShift = 5) {
const canvas = document.createElement('canvas');
const width = originalImg.width;
const height = originalImg.height;
canvas.width = width;
canvas.height = height;
const ctx = canvas.getContext('2d');
// Draw original image
ctx.drawImage(originalImg, 0, 0);
// Get image data to apply VHS / 16mm color effect
const imgData = ctx.getImageData(0, 0, width, height);
const data = imgData.data;
const outImgData = ctx.createImageData(width, height);
const outData = outImgData.data;
const shift = Math.max(0, Math.floor(colorShift));
// Process pixels for 16mm film / VHS Rip chromatic aberration and noise
for (let y = 0; y < height; y++) {
// Create tracking error wave effect typical of VHS
const trackingWave = Math.floor(Math.sin(y * 0.05) * (vhsIntensity / 10));
for (let x = 0; x < width; x++) {
const i = (y * width + x) * 4;
// Shift Red backwards for chromatic aberration
let srcXR = Math.min(width - 1, Math.max(0, x - shift + trackingWave));
let iR = (y * width + srcXR) * 4;
// Shift Blue forwards
let srcXB = Math.min(width - 1, Math.max(0, x + shift + trackingWave));
let iB = (y * width + srcXB) * 4;
// Keep Green centered but affected by wave
let srcXG = Math.min(width - 1, Math.max(0, x + trackingWave));
let iG = (y * width + srcXG) * 4;
// Add grain / noise
const noise = (Math.random() - 0.5) * vhsIntensity;
outData[i] = Math.min(255, Math.max(0, data[iR] + noise)); // Red
outData[i + 1] = Math.min(255, Math.max(0, data[iG + 1] + noise)); // Green
outData[i + 2] = Math.min(255, Math.max(0, data[iB + 2] + noise)); // Blue
outData[i + 3] = data[i + 3]; // Alpha
// Apply simple scanlines
if (y % 4 < 2) {
outData[i] = Math.max(0, outData[i] - 15);
outData[i + 1] = Math.max(0, outData[i + 1] - 15);
outData[i + 2] = Math.max(0, outData[i + 2] - 15);
}
}
}
ctx.putImageData(outImgData, 0, 0);
// Apply Video Tracker Text Overlay
const vhsFontSize = Math.max(12, Math.floor(height * 0.05));
ctx.textAlign = 'left';
ctx.textBaseline = 'top';
ctx.font = `${vhsFontSize}px "Courier New", monospace`;
ctx.fillStyle = 'rgba(255, 255, 255, 0.8)';
ctx.fillText("PLAY ► SP 0:00:00", 20, 20);
// Apply Translator Dub Text (Subtitle at bottom)
if (subtitleText && subtitleText.trim() !== "") {
ctx.textAlign = 'center';
ctx.textBaseline = 'bottom';
const subtitleSize = Math.max(16, Math.floor(height * 0.08));
ctx.font = `bold ${subtitleSize}px Arial, sans-serif`;
const textX = width / 2;
const textY = height - Math.max(10, Math.floor(height * 0.05));
// Subtitle stroke/outline
ctx.strokeStyle = 'black';
ctx.lineWidth = Math.max(3, Math.floor(subtitleSize * 0.15));
ctx.lineJoin = 'round';
ctx.strokeText(subtitleText, textX, textY);
// Subtitle fill (classic dubbed yellow)
ctx.fillStyle = '#fafa33';
ctx.fillText(subtitleText, textX, textY);
}
return canvas;
}
Apply Changes