Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
<html>
<head>
<title>Dithering Test</title>
</head>
<body>
<canvas></canvas>
<script>
var canvas = document.getElementsByTagName("canvas")[0];
var ctx = canvas.getContext('2d');
var id = ctx.getImageData(0, 0, 1, 1);
var img;
var image_data;
id.data[3] = 255;
function clip(x) {
return x < 0 ? 0 : (x > 255 ? 255 : x)
}
function setPixel(x, y, color) {
var index = (x + y * image_data.width) * 4;
image_data.data[index+0] = parseInt(color[0]+0.5);
image_data.data[index+1] = parseInt(color[1]+0.5);
image_data.data[index+2] = parseInt(color[2]+0.5);
image_data.data[index+3] = 255;
}
function color_diff(one, two) {
return [(one[0] - two[0]), (one[1] - two[1]), (one[2] - two[2])];
}
function color_add_err(x, y, err_red, err_green, err_blue) {
var index = (x + y * image_data.width) * 4;
image_data.data[index+0] = clip(image_data.data[index+0]+err_red)
image_data.data[index+1] = clip(image_data.data[index+1]+err_green)
image_data.data[index+2] = clip(image_data.data[index+2]+err_blue)
image_data.data[index+3] = 255;
}
function find_closest_palette_color(pixel) {
return (0.2126*pixel[0] + 0.7152*pixel[1] + 0.0722*pixel[2]) > 128 ? [255,255,255] : [0,0,0];
}
function get_pixel(x, y) {
var index = (x + y * image_data.width) * 4;
return [ image_data.data[index+0], image_data.data[index+1], image_data.data[index+2] ];
}
function rgb2bin(img_name) {
img = new Image();
img.src = img_name;
img.onload = function(){
canvas.height = img.height;
canvas.width = img.width;
ctx.drawImage(img, 0, 0, img.width, img.height);
image_data = ctx.getImageData(0, 0, img.width, img.height);
var oldpixel;
var newpixel;
var quant_error;
var err_red, err_green, err_blue;
for (var y = 0; y < img.height; y++) {
for (var x = 0; x < img.width; x++) {
oldpixel = get_pixel(x, y);
newpixel = find_closest_palette_color(oldpixel);
setPixel(x, y, newpixel);
quant_error = color_diff(oldpixel, newpixel);
err_red = quant_error[0];
err_green = quant_error[1];
err_blue = quant_error[2];
if (x+1 < img.width)
color_add_err(x+1, y, (7/16) * err_red, (7/16) * err_green, (7/16) * err_blue);
if (x-1 > 0 && y+1 < img.height)
color_add_err(x-1, y+1, (3/16) * err_red, (3/16) * err_green, (3/16) * err_blue);
if (y+1 < img.height)
color_add_err(x, y+1, (5/16) * err_red, (5/16) * err_green, (5/16) * err_blue);
if (x+1 < img.width)
color_add_err(x+1, y+1, (1/16) * err_red, (1/16) * err_green, (1/16) * err_blue);
}
}
ctx.putImageData(image_data, 0, 0);
}
}
document.body.onload = function(){rgb2bin(prompt("Enter image location"));}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment