ewie

good night

gay plural trans lesbian disaster. i've done some cursed programming stuff but i'm hoping that if i can just get better and hotter then maybe i can make something even worse


profile pic by @kyn

You must log in to comment.

in reply to @enbyss's post:

it took a lot more research than I expected not gonna lie. eventually the easiest path was by referencing color.js' code - since everything else had certain issues with em (because of floating point arithmetic etc.)

Oh! Basically I implemented multiple dithering methods, which mostly meant error propagation with different matrices and ordered dithering.

For ordered dithering, I could have just hardcoded the matrices - but at the same time I liked the idea of making a function to generate them for me. So I did and then I just use 'em!

Did it in rust and effectively extended the DynamicImage type of a library to apply filters and dithers on it. Lets me chain effects easily as a result.

i'm mainly having trouble wrapping my head around how ordered dithering generalizes from 1d grayscale to 3d color; all my dithering experiences thus far have been error diffusion. also, which colorspaces are you using? i've gotten somewhat mixed results with CIELab, but i'm not sure CIECAM16 or OKLab are much better for this

Ah okay so. In both cases you need to calculate the offset the same way. The only difference is that in 1-bit you collapse it into black or white, and in 3d colour you need a distance function to find the nearest colour in the palette.

Now theoretically the Lab-likes will be more accurate, however they're also more complex (take more time and hard to not make mistakes in) - so instead you can do the weighted euclidean distance (https://en.wikipedia.org/wiki/Color_difference).

Plus in terms of dithering, colour accuracy is more of a style decision more than a necessity. I did implement CIEDE2000, CIE76 and CIE94 though.

oh, oklab is really simple, actually, it's just a couple matrix transformations and some exponentiation. i still don't quite understand how ordered dithering works with this, though? do you just apply a standard grayscale dither mask and then find the closest color in the palette to that? that seems like it shouldn't work in some situations. (i'm not sure how to ordered-dither turquoise into the appropriate ratio of cyan and green.)

also, accuracy isn't essential, yeah, but i like to have an accurate basis to go off of before i begin stylizing things. gives me more control

maybe i haven't made it clear: i've already built my own color ditherer in cython, which i have already iterated from a minimal prototype. that's what i've used for my own experiments in dithering photos of cats. i'm using euclidean distance in increasingly fancy colorspaces, instead of using increasingly fancy color distance metrics

so you are just offsetting the image with a grayscale bayer mask? it's an interesting approach; the way that it can only dither between colors to optimize for luminance and not hue certainly makes the images look rather crisp.

well, there is of course this, which i barely understand: https://bisqwit.iki.fi/story/howto/dither/jy/

but the difficulty of splitting it per channel to work for hue-dithering is what initially gave me so much pause, yeah. good to know that just applying the grayscale mask works reasonably well regardless of that!

oh, on that note: have you considered using a blue noise mask for ordered dithering as well? the void-and-cluster algorithm is a bit of a pain to implement, but in my experience the grayscale results are rather good, and i'm curious as to how it will turn out in colour

so, having just implemented my own version of this: where'd you get the magic number 1/3 from? in my experiments, this scaling constant should be equal to the shortest distance between palette colors, otherwise the offset begins to have too much or too little influence on the texture of the image, but it seems to work just fine for you regardless of palette, even though i can't find one scaling-value which works for both a palette with 2 grayscale colors and a palette with 5

but in the article, it explains that N is derived from the number of colors in an equally-spaced-rgb-cube palette? (the 2^3N right before.) and it also says, later on, that r should be the minimum distance between palette colors. setting r to this made my ordered dithering work, but i'm not sure how to generalize this principle to arbitrary and non-uniform palettes