You can edit the below JavaScript code to customize the image tool.
Apply Changes
function processImage(originalImg, volumeNormalize = "100% / 100%", opusStats = "(-35.0dB/-14.0dB) Opus", ac3Stats = "(-31.9dB/-14.0dB) Ac3") {
// Create a canvas to draw the image and the overlay
const canvas = document.createElement('canvas');
canvas.width = originalImg.width;
canvas.height = originalImg.height;
const ctx = canvas.getContext('2d');
// Draw the original image as a background
ctx.drawImage(originalImg, 0, 0);
// Determine scale factor based on image size to ensure the overlay looks proportionate
let sf = Math.min(canvas.width / 640, canvas.height / 360);
if (sf < 0.6) sf = 0.6; // enforce minimum size for readability
if (sf > 2) sf = 2.0; // cap maximum size
// Dimensions and positioning for the "Stats for nerds" overlay box
const padding = 16 * sf;
const boxWidth = Math.min(520 * sf, canvas.width - (20 * sf));
const boxHeight = Math.min(300 * sf, canvas.height - (20 * sf));
const startX = 10 * sf;
const startY = 10 * sf;
// Draw semi-transparent black overlay box
ctx.fillStyle = 'rgba(0, 0, 0, 0.7)';
ctx.fillRect(startX, startY, boxWidth, boxHeight);
// Save context and apply clipping so text doesn't overflow the box
ctx.save();
ctx.beginPath();
ctx.rect(startX, startY, boxWidth, boxHeight);
ctx.clip();
// Top bar (Title)
ctx.fillStyle = '#ffffff';
ctx.font = `bold ${14 * sf}px "Roboto", "Helvetica Neue", Arial, sans-serif`;
ctx.textBaseline = 'top';
ctx.fillText("Stats for nerds", startX + padding, startY + padding);
// Top bar (Close 'X')
ctx.font = `${14 * sf}px sans-serif`;
ctx.fillText("✕", startX + boxWidth - padding - (12 * sf), startY + padding);
// Separator line
ctx.beginPath();
ctx.moveTo(startX + padding, startY + padding + 25 * sf);
ctx.lineTo(startX + boxWidth - padding, startY + padding + 25 * sf);
ctx.strokeStyle = 'rgba(255, 255, 255, 0.3)';
ctx.lineWidth = 1;
ctx.stroke();
// Data rows configuration
ctx.font = `${12 * sf}px "Roboto", "Helvetica Neue", Arial, sans-serif`;
const dataStartY = startY + padding + 35 * sf;
const rowHeight = 18 * sf;
// Constructing the mock stats and embedding the extracted audio stats
const lines = [
{ label: "Video ID / sCPN", value: "wXyZ1234567 / aBcDeFgHiJk" },
{ label: "Viewport / Frames", value: `${Math.round(canvas.width)}x${Math.round(canvas.height)} / 0 dropped` },
{ label: "Current / Optimal Res", value: `${canvas.width}x${canvas.height}@60 / ${canvas.width}x${canvas.height}@60` },
{ label: "Volume / Normalized", value: volumeNormalize },
{ label: "Audio (Opus)", value: opusStats },
{ label: "Audio (AC3)", value: ac3Stats },
{ label: "Codecs", value: "vp09.00.51.08.01.01.01.01.00 (303)" },
{ label: "Color", value: "bt709 / bt709" },
{ label: "Host", value: "r1---sn-nx5sn7e.googlevideo.com" },
{ label: "Connection Speed", value: "65000 Kbps" },
{ label: "Network Activity", value: "0 KB" },
{ label: "Buffer Health", value: "115.40 s" }
];
// Measure max label width to properly align the values in a column
let maxLabelWidth = 0;
for (const line of lines) {
maxLabelWidth = Math.max(maxLabelWidth, ctx.measureText(line.label).width);
}
const labelX = startX + padding;
const valueX = startX + padding + maxLabelWidth + (20 * sf);
// Draw each stat line
for (let i = 0; i < lines.length; i++) {
const y = dataStartY + (i * rowHeight);
// Hide rows if they exceed the box height
if (y + rowHeight > startY + boxHeight) break;
// Draw Label (slightly grayish text)
ctx.fillStyle = '#b3b3b3';
ctx.fillText(lines[i].label, labelX, y);
// Draw Value (bright white text)
ctx.fillStyle = '#ffffff';
ctx.fillText(lines[i].value, valueX, y);
}
// Restore context after clipping
ctx.restore();
return canvas;
}
Apply Changes