Reputation: 315
I am attempting to implement a Bayer ordered dithering matrix algorithm to convert a 24bit color image to a 3bit image. I have read the Wikipedia page, and several textbook sections on the topic and am a bit confused. This is what I have so far:
for (int y = 0; x < image.Height; y++)
{
for (int x = 0; x < image.Width; x++)
{
Color color = image.GetPixel(x,y);
color.R = color.R + bayer4x4[x % 4, y % 4];
color.G = color.G + bayer4x4[x % 4, y % 4];
color.B = color.B + bayer4x4[x % 4, y % 4];
image[x][y] = SetPixel(x, y, GetClosestColor(color, bitdepth);
}
}
However, I do not have a way of implementing GetClosestColor... how can I do this?
Also, I do not have the bayer4x4 matrix defined, I believe it should look like the following:
1, 9, 3, 11
13, 5, 15, 7
4, 12, 2, 10
16, 8, 14, 6
Upvotes: 1
Views: 1330
Reputation: 107
Here is my implementation of Bayer 4x4.
The both input and output are in 24 bit BGR format (for visualisation purposes).
In the output each pixel plane has value 0 or 255.
const int BAYER_PATTERN_4X4[4][4] = { // 4x4 Bayer Dithering Matrix. Color levels: 17
{ 15, 195, 60, 240 },
{ 135, 75, 180, 120 },
{ 45, 225, 30, 210 },
{ 165, 105, 150, 90 }
};
void makeColorDitherBayer4x4( BYTE* pixels, int width, int height ) noexcept
{
int col = 0;
int row = 0;
for( int y = 0; y < height; y++ )
{
row = y & 3; // % 4
for( int x = 0; x < width; x++ )
{
col = x & 3; // % 4
const pixel blue = pixels[x * 3 + 0];
const pixel green = pixels[x * 3 + 1];
const pixel red = pixels[x * 3 + 2];
pixels[x * 3 + 0] = (blue < BAYER_PATTERN_4X4[col][row] ? 0 : 255);
pixels[x * 3 + 1] = (green < BAYER_PATTERN_4X4[col][row] ? 0 : 255);
pixels[x * 3 + 2] = (red < BAYER_PATTERN_4X4[col][row] ? 0 : 255);
}
pixels += width * 3;
}
}
If you want to get the output as "compressed" data, you should replace this part of code:
pixels[x * 3 + 0] = (blue < BAYER_PATTERN_4X4[col][row] ? 0 : 255);
pixels[x * 3 + 1] = (green < BAYER_PATTERN_4X4[col][row] ? 0 : 255);
pixels[x * 3 + 2] = (red < BAYER_PATTERN_4X4[col][row] ? 0 : 255);
with something like this:
output.writeBit( (blue < BAYER_PATTERN_4X4[col][row] ? 0 : 1) );
output.writeBit( (green < BAYER_PATTERN_4X4[col][row] ? 0 : 1) );
output.writeBit( (red < BAYER_PATTERN_4X4[col][row] ? 0 : 1) );
Upvotes: 1