|
<!DOCTYPE html> |
|
<head> |
|
<meta charset="utf-8"> |
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.10.1/lodash.min.js"></script> |
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script> |
|
<style> |
|
</style> |
|
</head> |
|
|
|
<body> |
|
<img src="https://pbs.twimg.com/profile_images/3775316964/fe2ba0b0a4f0fb30aaef37c089553a8d.jpeg" width="400" /> |
|
<canvas id="canvas" width="500" height="500"></canvas> |
|
<script> |
|
var canvas = document.getElementById('canvas'); |
|
var ctx = canvas.getContext('2d'); |
|
d3.json('twitter_profile.json', function(image) { |
|
var imageData = ctx.getImageData(0,0,canvas.width, canvas.height); |
|
imageData.data = []; |
|
// turn it grayscale first |
|
for (var i = 0; i < image.length; i += 4) { |
|
if ((i / 4) % canvas.width === 0) { |
|
// for every new line, set error back to 0 |
|
error = 0; |
|
} |
|
var val = Math.max(image[i], image[i + 1], image[i + 2]); |
|
imageData.data[i] = val; |
|
imageData.data[i + 1] = val; |
|
imageData.data[i + 2] = val; |
|
imageData.data[i + 3] += 255; |
|
} |
|
|
|
var data = imageData.data; |
|
var threshold = 122.5; |
|
var nextRow = 4 * canvas.width; |
|
var numBlack = 0; |
|
// simple error diffusion to dither |
|
for (var i = 0; i < data.length; i += 4) { |
|
if ((i / 4) % canvas.width === 0) { |
|
// for every new line, set error back to 0 |
|
error = 0; |
|
} |
|
var oldPixel = data[i]; |
|
var newPixel = oldPixel > threshold ? 255 : 0; |
|
if (newPixel === 0) {numBlack += 1}; |
|
imageData.data[i] = newPixel; |
|
imageData.data[i + 1] = newPixel; |
|
imageData.data[i + 2] = newPixel; |
|
|
|
var pixels = {}; |
|
var error = (oldPixel - newPixel) >> 4; |
|
pixels[i + 4] = error * 7; |
|
pixels[i + nextRow - 4] = error * 3; |
|
pixels[i + nextRow] = error * 5; |
|
pixels[i + nextRow + 4] = error; |
|
|
|
_.each(pixels, function(error, j) { |
|
imageData.data[j] += error; |
|
imageData.data[j + 1] += error; |
|
imageData.data[j + 2] += error; |
|
}); |
|
} |
|
|
|
console.log(numBlack) |
|
ctx.putImageData(imageData, 0, 0); |
|
}); |
|
</script> |
|
</body> |