Skip to content

Instantly share code, notes, and snippets.

@liu7yong
Last active August 29, 2015 14:13
Show Gist options
  • Save liu7yong/2fe7fd35057fddef4b8a to your computer and use it in GitHub Desktop.
Save liu7yong/2fe7fd35057fddef4b8a to your computer and use it in GitHub Desktop.
html5 canvas test
<!DOCTYPE HTML>
<html>
<body>
<p>Original Image: </p>
<img id="demo_img" src="demo_small.png" alt="Original Image"/>
<p>Canvas:</p>
<canvas id="myCanvas" style="border:1px solid #000000;">your browser does not support the canvas tag </canvas>
<script type="text/javascript">
Filters = {};
Filters.getPixels = function(img) {
var c,ctx;
if (img.getContext) {
c = img;
try { ctx = c.getContext('2d'); } catch(e) {}
}
if (!ctx) {
c = this.getCanvas(img.width, img.height);
ctx = c.getContext('2d');
ctx.drawImage(img, 0, 0);
}
return ctx.getImageData(0,0,c.width,c.height);
};
Filters.getCanvas = function(w,h) {
var c = document.createElement('canvas');
c.width = w;
c.height = h;
return c;
};
Filters.filterImage = function(filter, image, var_args) {
var args = [this.getPixels(image)];
for (var i=2; i<arguments.length; i++) {
args.push(arguments[i]);
}
return filter.apply(null, args);
};
Filters.grayscale = function(pixels, args) {
var d = pixels.data;
for (var i=0; i<d.length; i+=4) {
var r = d[i];
var g = d[i+1];
var b = d[i+2];
// CIE luminance for the RGB
var v = 0.2126*r + 0.7152*g + 0.0722*b;
d[i] = d[i+1] = d[i+2] = v
}
return pixels;
};
Filters.brightness = function(pixels, adjustment) {
var d = pixels.data;
for (var i=0; i<d.length; i+=4) {
d[i] += adjustment;
d[i+1] += adjustment;
d[i+2] += adjustment;
}
return pixels;
};
Filters.threshold = function(pixels, threshold) {
var d = pixels.data;
for (var i=0; i<d.length; i+=4) {
var r = d[i];
var g = d[i+1];
var b = d[i+2];
var v = (0.2126*r + 0.7152*g + 0.0722*b >= threshold) ? 255 : 0;
d[i] = d[i+1] = d[i+2] = v
}
return pixels;
};
Filters.tmpCanvas = document.createElement('canvas');
Filters.tmpCtx = Filters.tmpCanvas.getContext('2d');
Filters.createImageData = function(w,h) {
return this.tmpCtx.createImageData(w,h);
};
Filters.convolute = function(pixels, weights, opaque) {
var side = Math.round(Math.sqrt(weights.length));
var halfSide = Math.floor(side/2);
var src = pixels.data;
var sw = pixels.width;
var sh = pixels.height;
var w = sw;
var h = sh;
var output = Filters.createImageData(w, h);
var dst = output.data;
var alphaFac = opaque ? 1 : 0;
for (var y=0; y<h; y++) {
for (var x=0; x<w; x++) {
var sy = y;
var sx = x;
var dstOff = (y*w+x)*4;
var r=0, g=0, b=0, a=0;
for (var cy=0; cy<side; cy++) {
for (var cx=0; cx<side; cx++) {
var scy = Math.min(sh-1, Math.max(0, sy + cy - halfSide));
var scx = Math.min(sw-1, Math.max(0, sx + cx - halfSide));
var srcOff = (scy*sw+scx)*4;
var wt = weights[cy*side+cx];
r += src[srcOff] * wt;
g += src[srcOff+1] * wt;
b += src[srcOff+2] * wt;
a += src[srcOff+3] * wt;
}
}
dst[dstOff] = r;
dst[dstOff+1] = g;
dst[dstOff+2] = b;
dst[dstOff+3] = a + alphaFac*(255-a);
}
}
return output;
};
if (!window.Float32Array)
Float32Array = Array;
Filters.convoluteFloat32 = function(pixels, weights, opaque) {
var side = Math.round(Math.sqrt(weights.length));
var halfSide = Math.floor(side/2);
var src = pixels.data;
var sw = pixels.width;
var sh = pixels.height;
var w = sw;
var h = sh;
var output = {
width: w, height: h, data: new Float32Array(w*h*4)
};
var dst = output.data;
var alphaFac = opaque ? 1 : 0;
for (var y=0; y<h; y++) {
for (var x=0; x<w; x++) {
var sy = y;
var sx = x;
var dstOff = (y*w+x)*4;
var r=0, g=0, b=0, a=0;
for (var cy=0; cy<side; cy++) {
for (var cx=0; cx<side; cx++) {
var scy = Math.min(sh-1, Math.max(0, sy + cy - halfSide));
var scx = Math.min(sw-1, Math.max(0, sx + cx - halfSide));
var srcOff = (scy*sw+scx)*4;
var wt = weights[cy*side+cx];
r += src[srcOff] * wt;
g += src[srcOff+1] * wt;
b += src[srcOff+2] * wt;
a += src[srcOff+3] * wt;
}
}
dst[dstOff] = r;
dst[dstOff+1] = g;
dst[dstOff+2] = b;
dst[dstOff+3] = a + alphaFac*(255-a);
}
}
return output;
};
var img = document.getElementById('demo_img');
img.addEventListener('load', function() {
var c = document.getElementById('myCanvas');
var idata = Filters.filterImage(Filters.grayscale, img);
c.width = idata.width;
c.height = idata.height;
var ctx = c.getContext('2d');
ctx.putImageData(idata, 0, 0);
});
// img = new Image();
// img.onload = function() {
// c.width = img.width;
// c.height = img.height;
//ctx.drawImage(img, 0, 0);
// Filters.filterImage(Filters.grayscale, img, null);
// };
// img.src = "demo_small.png";
</script>
</body>
</html>
@liu7yong
Copy link
Author

Place a png file named demo_small.png in the same directory, then open canvas.html to run the test.
If you run into error like follow:

Unable to get image data from canvas because the canvas has been tainted by cross-origin data.

Try to host these file into a server, the most simple way I know is:

python -m SimpleHTTPServer 8000

@liu7yong
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment