Hi all, I’m attempting to add a stylised order dithering effect on an image although I’ve been met with unexpected results. I have an 8 by 8 threshold matrix as follows:
int[] dither = new int[] { 1, 49, 13, 61, 4, 52, 16, 64,
33, 17, 45, 29, 36, 20, 48, 32,
9, 57, 5, 53, 12, 60, 8, 56,
41, 25, 37, 21, 44, 28, 40, 24,
3, 51, 15, 63, 2, 50, 14, 62,
35, 19, 47, 31, 34, 18, 46, 30,
11, 59, 7, 55, 10, 58, 6, 54,
43, 27, 39, 23, 42, 26, 38, 22 };
I just found this on the wikipedia page for ordered dithering and have been following the explanation in order to produce this effect myself. The algorithm producing the effect from this matrix is as closely resemblant of that explained in the wikipedia page and is as follows:
int w = image.getWidth();
int h = image.getHeight();
int bd = 64;
for(int y = 0; y < h; y++) {
for(int x = 0; x < w; x++) {
int c = pixels[y * w + x];
int d = dither[(y & 7) * 8 + (x & 7)];
int r = ((c >> 16) & 0xff) + d;
int g = ((c >> 8) & 0xff) + d;
int b = (c & 0xff) + d;
newpix[y * w + x] = 0x000000 | closestCol(r, bd) << 16 | closestCol(g, bd) << 8 | closestCol(b, bd);
}
}
This is just the method that reduces the amount of colours available in each channel:
private int closestCol(int c, int b) {
return c / b * b;
}
The above code simply adds the corresponding value from the threshold matrix to the image data and then attempts to find the nearest colour to it after rounding. The issue is that the dither values are quite high and saturate the channel of the pixel. I’ve tried averaging the channel colour with the corresponding dither value but that makes the screen far darker than it should be. Is there a detail that I’m missing whereby it adds the effect without harshly altering the tone of the image?
Just for reference, I’ve been consulting with this page: http://en.wikipedia.org/wiki/Ordered_dithering
Here’s a before and after dither comparison so you can see the results: http://i.imgur.com/9SWukYS.png
Thanks,
Paul