JavaScript: a sharpen filter and why clamping matters

A sharpening kernel emphasizes the difference between a pixel and its four neighbours: 5 times the center minus the neighbours above, below, left, and right. On a flat area the weights sum to 1, so the pixel is unchanged. Near an edge it exaggerates the contrast.

JavaScript
const width = 5;
const image = [];
for (let r = 0; r < 5; r++) {
  for (let c = 0; c < width; c++) {
    image.push(c < 2 ? 50 : 200);
  }
}

const clamp = (v) => Math.min(255, Math.max(0, v));
const at = (r, c) => image[r * width + c];

for (let r = 1; r < 4; r++) {
  const row = [];
  for (let c = 1; c < 4; c++) {
    const raw = 5 * at(r, c) - at(r - 1, c) - at(r + 1, c) - at(r, c - 1) - at(r, c + 1);
    row.push(clamp(raw));
  }
  console.log(row.join(" "));
}
Read the full lesson