I did the same like 2 weeks ago. In Rust. ^^
I'm still trying to improve it a little. https://git.ache.one/dither/tree/?h=%f0%9f%aa%b5
I didn't published it because it's hard to actually put dithered images on the web, you can't resize a dithered image. So on the web, you have to dither it on the fly. It's why, in the article, there is some artifacts in the images. I still need to learn about dithering.
Reference: https://sheep.horse/2022/12/pixel_accurate_atkinson_ditherin...
Cool links about dithering: - https://beyondloom.com/blog/dither.html - https://blog.maximeheckel.com/posts/the-art-of-dithering-and...
Why can't you resize it? Because of the filtering? You can turn that off in css, right?
I am the author of the sheep.horse link above, although here[0] is an updated link.
Even with filtering turned off you get slightly incorrect results, especially if you are resizing down where aliasing might completely ruin your image. Harsh black-and-white dithering is very susceptible to scaling artifacts.
If you want pixel perfect dithering for the screen you are viewing the page on, you need to do it client side. Whether or not this is worth the bother is up to you.
[0] https://sheep.horse/2023/1/improved_web_component_for_pixel-...
Note that this isn't a problem for blue noise based dithering; nevertheless, it's better if dithering is the last operation, and the result displayed 1:1 with pixel output.