Skip to content

Instantly share code, notes, and snippets.

@ucnv
Created December 28, 2009 04:24
Show Gist options
  • Save ucnv/264528 to your computer and use it in GitHub Desktop.
Save ucnv/264528 to your computer and use it in GitHub Desktop.
<!doctype html>
<html>
<head><title>Emulate fuba_recorder image conversion using canvas</title></head>
<body></body>
<script type="application/x-javascript">
var sources = [
'./bg_01.jpg',
'./bg_02.jpg',
'./bg_03.jpg',
'./bg_04.jpg',
'./bg_05.jpg',
'./bg_06.jpg',
'./bg_07.jpg',
'./bg_08.jpg',
'./bg_09.jpg',
'./bg_10.jpg',
].slice(0, 4 + Math.floor(Math.random() * 6));
var images = [];
sources.forEach(function(i) {
var img = new Image();
img.onload = function(ev) {
images.push(ev.target);
if(images.length == sources.length) process();
};
img.src = i;
});
function process() {
var n = images.length;
var w = Math.max.apply(this, images.map(function(i) { return i.width }));
var h = Math.max.apply(this, images.map(function(i) { return i.height }));
var c = [document.createElement('canvas'), document.createElement('canvas')];
c[0].width = c[1].width = w;
c[0].height = c[1].height = h;
var cc = c[0].getContext('2d');
var p;
// strip
var original = cc;
var filter = c[1].getContext('2d');
var horizontal = Math.random() > 0.5;
images.forEach(function(img, i) {
var sw = img.width, sh = img.height;
var o = horizontal ?
[img, 0, i * sh / n, sw, sh / n, 0, i * h / n, w, h / n] :
[img, i * sw / n, 0, sw / n, sh, i * w / n, 0, w / n, h];
var j = (i == 0) ? images.length - 1 : i - 1;
var f = horizontal ?
[img, 0, j * sh / n, sw, sh / n, 0, j * h / n, w, h / n] :
[img, j * sw / n, 0, sw / n, sh, j * w / n, 0, w / n, h];
original.drawImage.apply(original, o);
filter.drawImage.apply(filter, f);
});
var originald = original.getImageData(0, 0, w, h);
var filterd = filter.getImageData(0, 0, w, h);
var base = [];
p = [difference, plus, multiply, bumpmap][Math.floor(Math.random() * 4)];
p(originald.data, filterd.data, base);
// gradation
var mdata = images.slice(0, 3).map(function(img, i) {
cc.drawImage(img, 0, 0);
var s = cc.getImageData(0, 0, w, h);
var d = [];
var hues = (i - 0.5) / n, huee = (i + 1.5) / n;
if(hues < 0) hues = 0;
if(huee > 1) huee = 1;
convertHue(s.data, hues, huee, d);
return d;
});
var mask = [], pd = [];
mdata.push(mask);
plus(mdata[0], mdata[1], pd);
compositeMask(pd, mdata[1], mdata[2], mask);
var result = cc.createImageData(w, h);
p = [difference, multiply][Math.floor(Math.random() * 2)];
p(mask, base, result.data);
cc.putImageData(result, 0, 0);
document.body.appendChild(cc.canvas);
}
function difference(p, q, r) {
for(var i = 0; i < p.length; i++) {
r[i] = (i % 4 != 3) ? p[i] + q[i] - 2 * Math.min(p[i], q[i]) : 255;
}
}
function plus(p, q, r) {
for(var i = 0; i < p.length; i++) {
r[i] = (i % 4 != 3) ? p[i] + q[i] : 255;
if(r[i] > 255) r[i] = 255;
}
}
function multiply(p, q, r) {
for(var i = 0; i < p.length; i++) {
r[i] = (i % 4 != 3) ? 255 * (p[i] / 255 * q[i] / 255) : 255;
}
}
function bumpmap(p, q, r) {
for(var i = 0; i < p.length; i += 4) {
var intensity = 0.299 * p[i] + 0.587 * p[i + 1] + 0.114 * p[i + 2];
r[i] = 1 / 255 * intensity * q[i];
r[i + 1] = 1 / 255 * intensity * q[i + 1];
r[i + 2] = 1 / 255 * intensity * q[i + 2];
r[i + 3] = 255;
}
}
function convertHue(s, hues, huee, d) {
for(var i = 0; i < s.length; i += 4) {
var hue;
var r = s[i] / 255, g = s[i + 1] / 255, b = s[i + 2] /255;
var max = Math.max(r, g, b), min = Math.min(r, g, b);
var delta = max - min, delta_2 = delta / 2;
if(delta == 0) {
hue = 0;
} else {
if(r == max) {
hue = ((max - b) / 6 + delta_2 - (max - g) / 6 + delta_2) / delta;
} else if(g == max) {
hue = 1 / 3 + ((max - r) / 6.0 + delta_2 -(max - b) / 6 + delta_2) /delta;
} else {
hue = 2 / 3 + ((max - g) / 6 + delta_2 - (max - r) / 6 + delta_2) / delta;
}
if(hue < 0) hue += 1;
if(hue > 0) hue -= 1;
}
if(hue > hues && hue < huee) {
d[i] = s[i];
d[i + 1] = s[i + 1];
d[i + 2] = s[i + 2];
d[i + 3] = s[i + 3];
} else {
d[i] = d[i + 1] = d[i + 2] = (s[i] + s[i + 1] + s[i + 2]) / 3;
d[i + 3] = 255;
}
}
}
function compositeMask(p, q, m, r) { // tekitou
for(var i = 0; i < p.length; i += 4) {
var opacity = (m[i] + m[i + 1] + m[i + 2]) / 3 / 255;
r[i] = p[i] * opacity + q[i] * (1 - opacity);
r[i + 1] = p[i + 1] * opacity + q[i + 1] * (1 - opacity);
r[i + 2] = p[i + 2] * opacity + q[i + 2] * (1 - opacity);
r[i + 3] = 255;
}
}
</script>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment