<canvas id="canvas" width="500" height="500"></canvas>
var photo = new Image();
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
ctx.fillStyle = 'black';
ctx.font = '24px monospace';
ctx.fillText('Loading image...', 20, 40);
function toasterGradient(width, height) {
var texture = document.createElement('canvas');
var ctx = texture.getContext('2d');
texture.width = width;
texture.height = height;
// Fill a Radial Gradient
// https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/createRadialGradient
var gradient = ctx.createRadialGradient(width / 2, height / 2, 0, width / 2, height / 2, width * 0.6);
gradient.addColorStop(0, "#804e0f");
gradient.addColorStop(1, "#3b003b");
ctx.fillStyle = gradient;
ctx.fillRect(0, 0, width, height);
return ctx
}
function blend (background, foreground, width, height, transform) {
var bottom = background.getImageData(0, 0, width, height);
var top = foreground.getImageData(0, 0, width, height);
for (var i = 0, size = top.data.length; i < size; i += 4) {
// red
top.data[i + 0] = transform(bottom.data[i + 0], top.data[i + 0]);
// green
top.data[i + 1] = transform(bottom.data[i + 1], top.data[i + 1]);
// blue
top.data[i + 2] = transform(bottom.data[i + 2], top.data[i + 2]);
// the fourth slot is alpha. We don't need that (so skip by 4)
}
return top
}
function render() {
// Scale so that the image fills the container
var width = window.innerWidth;
var scale = width / photo.naturalWidth;
var height = photo.naturalHeight * scale;
canvas.width = width;
canvas.height = height;
ctx.drawImage(photo, 0, 0, width, height);
var gradient = toasterGradient(width, height);
var screen = blend(ctx, gradient, width, height, function(bottomPixel, topPixel) {
return 255 - (255 - topPixel) * (255 - bottomPixel) / 255;
})
var colorCorrected = colorMatrix(screen, { contrast: 30, brightness: -30 });
ctx.putImageData(colorCorrected, 0, 0);
}
photo.onload = render;
photo.crossOrigin = "Anonymous";
photo.src = "https://s3.amazonaws.com/share.viget.com/images/viget-works.jpg?bust=true";
/**
* Color Matrix
*
* A simplification of the color matrix class provided by
* EaselJS
*
* www.createjs.com/docs/easeljs/files/easeljs_filters_ColorFilter.js.html#l41
*/
window.colorMatrix = (function() {
var DELTA_INDEX = [
0, 0.01, 0.02, 0.04, 0.05, 0.06, 0.07, 0.08, 0.1, 0.11,
0.12, 0.14, 0.15, 0.16, 0.17, 0.18, 0.20, 0.21, 0.22, 0.24,
0.25, 0.27, 0.28, 0.30, 0.32, 0.34, 0.36, 0.38, 0.40, 0.42,
0.44, 0.46, 0.48, 0.5, 0.53, 0.56, 0.59, 0.62, 0.65, 0.68,
0.71, 0.74, 0.77, 0.80, 0.83, 0.86, 0.89, 0.92, 0.95, 0.98,
1.0, 1.06, 1.12, 1.18, 1.24, 1.30, 1.36, 1.42, 1.48, 1.54,
1.60, 1.66, 1.72, 1.78, 1.84, 1.90, 1.96, 2.0, 2.12, 2.25,
2.37, 2.50, 2.62, 2.75, 2.87, 3.0, 3.2, 3.4, 3.6, 3.8,
4.0, 4.3, 4.7, 4.9, 5.0, 5.5, 6.0, 6.5, 6.8, 7.0,
7.3, 7.5, 7.8, 8.0, 8.4, 8.7, 9.0, 9.4, 9.6, 9.8,
10.0
];
function multiply (a, b) {
var i, j, k, col = [];
for (i=0;i<5;i++) {
for (j=0;j<5;j++) {
col[j] = a[j+i*5];
}
for (j=0;j<5;j++) {
var val=0;
for (k=0;k<5;k++) {
val += b[j+k*5]*col[k];
}
a[j+i*5] = val;
}
}
};
function colorMatrix (imageData, options) {
var brightness = options.brightness || 0
var contrast = options.contrast || 0
var matrix = [
1,0,0,0,0,
0,1,0,0,0,
0,0,1,0,0,
0,0,0,1,0,
0,0,0,0,1
];
// Contrast
var x;
if (contrast < 0) {
x = 127 + contrast / 100 * 127;
} else {
x = contrast % 1;
if (x == 0) {
x = DELTA_INDEX[contrast];
} else {
x = DELTA_INDEX[(contrast<<0)]*(1-x)+DELTA_INDEX[(contrast<<0)+1] * x;
}
x = x * 127 + 127;
}
multiply (matrix, [
x/127,0,0,0,0.5*(127-x),
0,x/127,0,0,0.5*(127-x),
0,0,x/127,0,0.5*(127-x),
0,0,0,1,0,
0,0,0,0,1
]);
// Brightness
multiply (matrix,[
1,0,0,0, brightness,
0,1,0,0, brightness,
0,0,1,0, brightness,
0,0,0,1,0,
0,0,0,0,1
])
// Apply Filter
var data = imageData.data;
var l = data.length;
var r,g,b,a;
var m0 = matrix[0], m1 = matrix[1], m2 = matrix[2], m3 = matrix[3], m4 = matrix[4];
var m5 = matrix[5], m6 = matrix[6], m7 = matrix[7], m8 = matrix[8], m9 = matrix[9];
var m10 = matrix[10], m11 = matrix[11], m12 = matrix[12], m13 = matrix[13], m14 = matrix[14];
var m15 = matrix[15], m16 = matrix[16], m17 = matrix[17], m18 = matrix[18], m19 = matrix[19];
for (var i=0; i<l; i+=4) {
r = data[i];
g = data[i+1];
b = data[i+2];
a = data[i+3];
data[i] = r*m0+g*m1+b*m2+a*m3+m4; // red
data[i+1] = r*m5+g*m6+b*m7+a*m8+m9; // green
data[i+2] = r*m10+g*m11+b*m12+a*m13+m14; // blue
data[i+3] = r*m15+g*m16+b*m17+a*m18+m19; // alpha
}
return imageData
}
return colorMatrix
})()
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.