fellow devs!
I am trying to dither a 8-bit grayscale image to a 2-bit / 4 color image with an ordered dithering based on a Bayer 8×8 matrix. My result is somewhat there, but not quite. I kept banging my head at the problem but can’t figure out where I went wrong so any help would be greatly appreciated.
Here’s my code:
// image_array_2d is a 2d array of grayscale values from 0-255
// matrix is a 2d array with values normalized to be between 0.0 and 1.0
// LUT is an array of 8-bit values, in this case [0, 85, 170, 255]
const MAX = 255
const image_height = image_array_2d.length
const image_width = image_array_2d[0].length
for (let y = 0; y < image_height; y++)
{
for (let x = 0; x < image_width; x++)
{
const threshold = (matrix[y % 8][x % 8]) * MAX
let pixel_value = image_array_2d[y][x];
//pixel_value = gamma_correct(pixel_value)
// find closest value to pixel in LUT
let value_current, value_prev
let closest = lut[0]
for (let i = 0; i < lut.length; i++)
{
const closestDifference = Math.abs(closest - pixel_value);
const currentDifference = Math.abs(lut[i] - pixel_value);
console.log(currentDifference + " / " + closestDifference)
if (currentDifference < closestDifference)
{
value_prev = lut[i-1]
value_current = lut[i]
closest = value_current
console.log(closest)
}
}
let new_value = 0
new_value = pixel_value > threshold ? value_current : value_prev
new_value = pixel_value >= MAX ? MAX : new_value
image_array_2d[y][x] = new_value
}
}
Just for safety, that’s my Bayer matrix before its values get normalized to 0.0 – 1.0
[ 0, 32, 8, 40, 2, 34, 10, 42],
[48, 16, 56, 24, 50, 18, 58, 26],
[12, 44, 4, 36, 14, 46, 6, 38],
[60, 28, 52, 20, 62, 30, 54, 22],
[ 3, 35, 11, 43, 1, 33, 9, 41],
[51, 19, 59, 27, 49, 17, 57, 25],
[15, 47, 7, 39, 13, 45, 5, 37],
[63, 31, 55, 23, 61, 29, 53, 21]
(The following images have been scaled up by 400% for convenience)
This is the image I test my algorithm with:

And this is the intended target:

However, this is the result of the above code with the LUT array being [0, 85, 170, 255]
