-
Notifications
You must be signed in to change notification settings - Fork 57
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
dithSerp palette issue #30
Comments
honestly, i think the original dithering code was adapted from here [2] and even there, there's a comment questioning whether the hz kernel offsets should be reversed or not. it made sense to me to do this because the idea of error diffusion is never to spread the error to already processed pixels and if you're alternating the scan direction without reflecting the kernel horizontally, you're doing exactly that. i think the dithering code in general needs a careful review, which i never really did given that the results looked subjectively correct. [1] http://leeoniya.github.io/RgbQuant.js/demo/ |
@leeoniya Well I was planning to use your library as an easy to go dropin for my SIXEL encoding (https://github.com/jerch/node-sixel, currently only the decoder is implemented). SIXEL is bound to 16 or 256 palettes, thus the need for a quantization/dithering step. I dont want to deal with that on my own, advanced image processing is beyond the scope of the SIXEL lib. So what do you suggest? Disabling the serpentine for now? Still works good enough for my purpose (well mostly), disabling whole dithering though is not an option as it produces to many artefacts. |
if you need to use it today, i would avoid using if you have any spare cycles and want to try reviewing the dithering loop yourself, go ahead. it's not super complicated, just needs to be carefully reviewed. you can use these as references: [1] [2]. the meat of the dither step is just 70 lines: https://github.com/leeoniya/RgbQuant.js/blob/master/src/rgbquant.js#L241-L310 [1] http://www.tannerhelland.com/4660/dithering-eleven-algorithms-source-code/ |
@leeoniya Will see if I find some time to look into it. For now I do a second ED calculation to get rid of the suprious colors. You can already test this in a SIXEL capable terminal (like xterm started with
😸 |
@leeoniya So the kernel should be reflected for serpentine dither, every time you go in reverse right? I'm implementing my own dithering library and I can't find any information on this. I know you're having trouble here, did you figure it out? In any case I can't see how not reflecting it would be a good idea. |
yes, i think so. you can see that all the kernels are arranged with nothing to north or west of X, which would imply eastwards and southwards iteration. if you're reversing along x, then the kernel needs to be x-reflected. |
Ok, thanks! And that's a helpful link. Here, I just implemented serpentine dithering. Can't be 100% sure I'm doing it right, but I think I am. Simple 2D matrix regular: Simple 2D matrix serpentine: Make sure to view these images at 100% size. The serpentine definitely looks smoother. Not sure if that helps anything, but it might be useful as a reference for creating a black and white gradient test case. |
nice :) |
it does feel like serpentine may not provide the best "improvement" since it's pretty directional. you may want to look into Riemersma Dither, particularly one that follows a Hilbert space-filling curve. this might give you less directional dithering. https://www.compuphase.com/riemer.htm i think igor implemented this in his RgbQuant offshoot: https://github.com/ibezkrovnyi/image-quantization also, here is way too much additional dithering info: https://bisqwit.iki.fi/story/howto/dither/jy/ |
Yep, I'm aware of those methods and plan on implementing them later. I just also wanted to have serpentine available. |
If
dithSerp
is set totrue
it seems to introduce colors that are not in the palette for small palettes, repro:The palette now contains:
the colors of
out
are (unordered):The last entry is not in the palette. If you add more colors or gradients to the original image, more spurious colors will pop up. Is this a missing/misplaced nearest color matching in
reduce
?The text was updated successfully, but these errors were encountered: