Skip to content

Instantly share code, notes, and snippets.

@ntzyz
Created May 25, 2017 06:58
Show Gist options
  • Save ntzyz/9b787564d3f17111695a2427d29c97bd to your computer and use it in GitHub Desktop.
Save ntzyz/9b787564d3f17111695a2427d29c97bd to your computer and use it in GitHub Desktop.
<!doctype html>
<html>
<head>
<title></title>
<meta charset="UTF-8" />
</head>
<body>
<table>
<tr>
<td>sigma</td>
<td><input id="sigma" type="text" value="1.5" disabled/></td>
</tr>
<tr>
<td>radius</td>
<td><input id="radius" type="text" value="10"/></td>
</tr>
<tr>
<td></td>
<td><button onclick="GaussianBlur()">Start</button></td>
</tr>
</table>
<canvas style="border: 1px solid black;"></canvas>
<script>
let canvas = document.querySelector('canvas');
let ctx = canvas.getContext('2d');
let img = new Image();
img.src = './2.png';
img.onload = e => {
canvas.width = img.naturalWidth;
canvas.height = img.naturalHeight;
ctx.drawImage(img, 0, 0, img.naturalWidth, img.naturalHeight);
}
function G(u, v) {
let sigma = Number(document.querySelector('#sigma').value);
return (1 / (2 * Math.PI * Math.pow(sigma, 2))) * Math.pow(Math.E, -(u ** 2 + v ** 2) / (2 * sigma ** 2));
}
function GaussianBlur() {
let src = ctx.getImageData(0, 0, canvas.width, canvas.height);
let radius = Number(document.querySelector('#radius').value);
let sigma = (radius - 1) / 6;
document.querySelector('#sigma').value = sigma;
// Construct matrix
let sum = 0;
let matrix = window.matrix = new Array(2 * radius + 1).fill(0).map(() => new Array(2 * radius + 1));
for (let u = -radius; u <= radius; u++) {
for (let v = -radius; v <= radius; v++) {
matrix[radius + u][radius + v] = G(u, v);
sum += matrix[radius + u][radius + v];
}
}
for (let u = -radius; u <= radius; u++) {
for (let v = -radius; v <= radius; ++v) {
matrix[radius + u][radius + v] /= sum;
}
}
let dest = ctx.getImageData(0, 0, canvas.width, canvas.height);
let setPixel = (x, y, r, g, b) => {
dest.data[(y * canvas.width + x) * 4 + 0] = r;
dest.data[(y * canvas.width + x) * 4 + 1] = g;
dest.data[(y * canvas.width + x) * 4 + 2] = b;
}
let getPixel = (x, y) => {
return [
src.data[(y * canvas.width + x) * 4 + 0],
src.data[(y * canvas.width + x) * 4 + 1],
src.data[(y * canvas.width + x) * 4 + 2],
];
}
for (let x = radius; x < canvas.width - radius; ++x) {
for (let y = radius; y <= canvas.height - radius; ++y) {
let r = 0, g = 0, b = 0;
for (let u = -radius; u <= radius; u++) {
for (let v = -radius; v <= radius; v++) {
let pixel = getPixel(x + u, y + v);
r += pixel[0] * matrix[radius + u][radius + v];
g += pixel[1] * matrix[radius + u][radius + v];
b += pixel[2] * matrix[radius + u][radius + v];
}
}
setPixel(x, y, r, g, b);
}
}
ctx.putImageData(dest, 0, 0, 0, 0, canvas.width, canvas.height);
}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment