Last active
January 3, 2016 17:08
-
-
Save primats/be7a5b565471e672810f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<style> | |
.bg { background: | |
url(http://primat.org/picture/raznoe/png-background.png); | |
padding: 00px; | |
display: inline-block; | |
float: left; | |
} | |
div#buttons button {margin-right:5px;margin-bottom:10px;} | |
div#buttons input {margin-left:-5px;margin-right:5px; | |
text-align:center;padding-left:4px;padding-right:4px;max-width:60px;} | |
</style> | |
<div class="bg" ><canvas id="canvas" ></canvas></div> | |
<hr style="margin-bottom:4px;width:100%;"> | |
<div > <div id="buttons"><button style="float:left;" | |
id="reset">Сброс</button> </div></div> | |
<pre id="fn" style="width:100%;min-height:40px;"></pre> | |
<hr style="margin-bottom:4px;width:100%;"> | |
<script> | |
function CanvasImage(canvas, src) { | |
// load image in canvas | |
var context = canvas.getContext('2d'); | |
var i = new Image(); | |
var that = this; | |
i.onload = function(){ | |
canvas.width = i.width; | |
canvas.height = i.height; | |
context.drawImage(i, 0, 0, i.width, i.height); | |
// remember the original pixels | |
that.original = that.getData(); | |
}; | |
i.src = src; | |
// cache these | |
this.context = context; | |
this.image = i; | |
} | |
CanvasImage.prototype.getData = function() { | |
return this.context.getImageData(0, 0, this.image.width, this.image.height); | |
}; | |
CanvasImage.prototype.setData = function(data) { | |
return this.context.putImageData(data, 0, 0); | |
}; | |
CanvasImage.prototype.reset = function() { | |
this.setData(this.original); | |
} | |
CanvasImage.prototype.transform = function(fn, factor) { | |
var olddata = this.original; | |
var oldpx = olddata.data; | |
var newdata = this.context.createImageData(olddata); | |
var newpx = newdata.data | |
var res = []; | |
var len = newpx.length; | |
for (var i = 0; i < len; i += 4) { | |
res = fn.call(this, oldpx[i], oldpx[i+1], oldpx[i+2], oldpx[i+3], factor, i); | |
newpx[i] = res[0]; // r | |
newpx[i+1] = res[1]; // g | |
newpx[i+2] = res[2]; // b | |
newpx[i+3] = res[3]; // a | |
} | |
this.setData(newdata); | |
}; | |
var transformador = new CanvasImage( | |
$('canvas'), | |
'http://primat.org/picture/raznoe/zrazok.gif' | |
); | |
var manipuladors = [ | |
{ | |
name: 'rgb -> brg', | |
cb: function(r, g, b) { | |
return [b, r, g, 255]; | |
} | |
}, | |
{ | |
name: 'rgb -> rbg', | |
cb: function(r, g, b) { | |
return [r, b, g, 255]; | |
} | |
}, | |
{ | |
name: 'rgb -> gbr', | |
cb: function(r, g, b) { | |
return [g, b, r, 255]; | |
} | |
}, | |
{ | |
name: 'rgb -> grb', | |
cb: function(r, g, b) { | |
return [g, r ,b, 255]; | |
} | |
}, | |
{ | |
name: 'rgb -> bgr', | |
cb: function(r, g, b) { | |
return [b, g, r, 255]; | |
} | |
}, | |
{ | |
name: 'негатив', | |
cb: function(r, g, b) { | |
return [255 - r, 255 - g, 255 - b, 255]; | |
} | |
}, | |
{ | |
name: 'серый', | |
cb: function(r, g, b) { | |
var avg = 0.3 * r + 0.59 * g + 0.11 * b; | |
return [avg, avg, avg, 255]; | |
} | |
}, | |
{ | |
name: 'сепия', | |
cb: function(r, g, b) { | |
var avg = 0.3 * r + 0.59 * g + 0.11 * b; | |
return [avg + 100, avg + 50, avg, 255]; | |
} | |
}, | |
{ | |
name: 'сепия 2', | |
cb: function(r, g, b) { | |
return [ | |
(r * 0.393 + g * 0.769 + b * 0.189 ) / 1.351, | |
(r * 0.349 + g * 0.686 + b * 0.168 ) / 1.203, | |
(r * 0.272 + g * 0.534 + b * 0.131 ) / 2.140, | |
255 | |
]; | |
} | |
}, | |
{ | |
name: 'прозрачно', | |
cb: function(r, g, b, a, factor) { | |
return [r, g, b, factor]; | |
}, | |
factor: "0-255" | |
}, | |
{ | |
name: 'градиент', | |
cb: function(r, g, b, a, factor, i) { | |
var total = this.original.data.length; | |
return [r, g, b, factor + 255 * (total - i) / total]; | |
}, | |
factor: " 0-255" | |
}, | |
{ | |
name: 'гамма', | |
cb: function(r, g, b, a, factor) { | |
return [ | |
Math.pow(r / 255, factor) * 255, | |
Math.pow(g / 255, factor) * 255, | |
Math.pow(b / 255, factor) * 255, | |
255 | |
]; | |
}, | |
factor: '2-10' | |
}, | |
{ | |
name: 'без зеленого', | |
cb: function(r, g, b) { | |
return [r, 0, b, 255]; | |
} | |
}, | |
{ | |
name: 'макс.зеленый', | |
cb: function(r, g, b) { | |
return [r, 255, b, 255]; | |
} | |
}, | |
{ | |
name: 'только зеленый', | |
cb: function(r, g, b) { | |
return [0, g, 0, 255]; | |
} | |
}, | |
{ | |
name: 'яркость', | |
cb: function(r, g, b, a, factor) { | |
return [r + factor, g + factor, b + factor, 255]; | |
}, | |
factor: '0-255' | |
}, | |
{ | |
name: 'шум', | |
cb: function(r, g, b, a, factor) { | |
var rand = (0.5 - Math.random()) * factor; | |
return [r + rand, g + rand, b + rand, 255]; | |
}, | |
factor: '0 - 500' | |
} | |
]; | |
// UI | |
function $(id) {return document.getElementById(id)} | |
manipuladors.forEach(function(m) { | |
var b = document.createElement('button'); | |
b.innerHTML = m.name; | |
b.onclick = function() { | |
var factor = null; | |
if (b.nextSibling.nodeName.toUpperCase() === 'INPUT') { | |
factor = parseInt(b.nextSibling.value, 10); | |
if (isNaN(factor)) { | |
factor = 0; | |
} | |
} | |
transformador.transform(m.cb, factor); | |
$('fn').innerHTML = m.cb.toString(); | |
}; | |
$('buttons').appendChild(b); | |
var label = m.factor; | |
if (label) { | |
var input = document.createElement('input'); | |
input.placeholder = label; | |
$('buttons').appendChild(input); | |
} | |
}) | |
$('reset').onclick = function(){ | |
transformador.reset(); | |
$('fn').innerHTML = ''; | |
}; | |
</script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment