Skip to content

Instantly share code, notes, and snippets.

@jorinvo
Last active August 29, 2015 14:02
Show Gist options
  • Save jorinvo/df70938d061b2b43c26d to your computer and use it in GitHub Desktop.
Save jorinvo/df70938d061b2b43c26d to your computer and use it in GitHub Desktop.
Demo for Basic Image Filtering Using a Canvas Element
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Demo for Basic Image Filtering Using a Canvas Element</title>
</head>
<body>
<div>
<input type="file" id="loader">
<select id="filter">
<option value="original">No Filter</option>
<option value="lowpass">Soft Focus</option>
<option value="highpass">Highpass</option>
<option value="edges">Sharp Edges</option>
</select>
<a href="//gist.github.com/jorin-vogel/df70938d061b2b43c26d">view source</a>
</div>
<canvas id="pic"></canvas>
<script>
!function() {
var width, height, i, x, y, r, g, b, xWithOffset, yWithOffset, pos, kernel, baseImageData;
var pic = document.getElementById('pic');
var ctx = pic.getContext('2d');
var selectedFilter = 'original';
function applyFilter() {
var res = ctx.createImageData(baseImageData);
var pixels = baseImageData.data;
var filter = filters[selectedFilter];
for (y = 0; y < height; y++) {
for (x = 0; x < width; x++) {
r = g = b = 0;
for (i = 0; i < kernelCoordinates.length; i += 2) {
// restrict to pixels inside image
xWithOffset = restrict( x + kernelCoordinates[i] , width );
yWithOffset = restrict( y + kernelCoordinates[i+1] , height );
pos = 4 * ( yWithOffset * width + xWithOffset );
kernel = filter.kernel[i/2];
r += pixels[pos] * kernel;
g += pixels[pos+1] * kernel;
b += pixels[pos+2] * kernel;
}
pos = 4 * ( y * width + x );
res.data[pos] = transform(r, filter);
res.data[pos+1] = transform(g, filter);
res.data[pos+2] = transform(b, filter);
res.data[pos+3] = pixels[pos+3]; // don't manipulate alpha value
}
}
ctx.putImageData(res, 0, 0);
}
function loadImage(src) {
var img = new Image();
img.onload = function() {
width = pic.width = img.width;
height = pic.height = img.height;
ctx.drawImage(img, 0, 0);
baseImageData = ctx.getImageData(0, 0, width, height);
applyFilter();
};
img.src = src;
}
//
// FILTERS
//
var filters = {
original: {
kernel: [
0, 0, 0,
0, 1, 0,
0, 0, 0
],
scale: 1,
offset: 0
},
lowpass: {
kernel: [
1, 1, 1,
1, 1, 1,
1, 1, 1
],
scale: 9,
offset: 0
},
highpass: {
kernel: [
-1, -1, -1,
-1, 8, -1,
-1, -1, -1
],
scale: 9,
offset: 128
},
edges: {
kernel: [
-1, -1, -1,
-1, 17, -1,
-1, -1, -1
],
scale: 9,
offset: 0
}
};
//
// HELPER
//
var kernelCoordinates = [
-1, -1,
0, -1,
1, -1,
-1, 0,
0, 0,
1, 0,
-1, 1,
0, 1,
1, 1
];
function restrict(val, max) {
if (val < 0) return 0;
if (val > max) return max;
return val;
}
function transform(val, filter) {
return restrict(val / filter.scale + filter.offset, 255);
}
//
// USER EVENTS
//
document.getElementById('loader').addEventListener('change', function(changeEvent) {
var reader = new FileReader();
reader.onload = function(loadEvent) {
loadImage(loadEvent.target.result);
};
reader.readAsDataURL(changeEvent.target.files[0]);
});
var filterElement = document.getElementById('filter');
filterElement.addEventListener('change', function() {
selectedFilter = filterElement.value;
applyFilter();
});
//
// INIT
//
loadImage('test.jpg');
}();
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment