Skip to content
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

Uint8Array image and serpentine dithering not supported? #33

Closed
Seventh7th-Son opened this issue Jul 28, 2020 · 6 comments
Closed

Uint8Array image and serpentine dithering not supported? #33

Seventh7th-Son opened this issue Jul 28, 2020 · 6 comments

Comments

@Seventh7th-Son
Copy link

Hi Leon,

After spending countless hours trying to find coding errors on my side, I finally decided to look at your code for serpentine dithering. Looks like dithering is only supported with Uin8Array images rgbQuant? Is this correct? I need to convert a Uint8Array to a data.buf32 ? Google?

if (!kernel || !kernels[kernel]) { throw 'Unknown dithering kernel: ' + kernel; }

var ds = kernels[kernel];

	var data = getImageData(img),

// buf8 = data.buf8, << Uint8Array not supported ????

		buf32 = data.buf32,
		width = data.width,
		height = data.height,
		len = buf32.length;
	var dir = serpentine ? -1 : 1;
	for (var y = 0; y < height; y++) {
		if (serpentine)
			dir = dir * -1;

Thank you,
Wayne

@leeoniya
Copy link
Owner

leeoniya commented Jul 28, 2020

uint8 arrays should be supported just fine: https://github.com/leeoniya/RgbQuant.js/blob/master/src/rgbquant.js#L865

but serpentine dithering is busted in general, see #30. (if you'd like to help find & fix the issue, that would be cool :).

while i have not worked on RgbQuant for quite some time, i actually have the beginnings of a quantizer prototype with more of an octree-type internal architecture for pallete building that works in HSLuv color space rather than RGB. this should have noticiable quality improvements while eliminating a lot of unnecessary knobs and properly handling cases with small pallete counts like #12.

the long term plan is to be able to re-use the dithering code from here, so any fixes to serpentine will also carry over to the next rgbquant version.

@Seventh7th-Son
Copy link
Author

Update, There is an output but, no changes happen when switching dithSerp true and false. Been up and down the dithKern, dithDelta, dithSerp , colors, minHueCols settings.

Looking at the ing.buf32 is one long array, but the demo has actual image w x h in the compcube_th.jsg

I would like to help, but my Javascript talents are still on the learning upswing. I do have 10 years professional work experience with Delphi, DB programming on SQL server... Not a new kid on the block.

@leeoniya
Copy link
Owner

i will need your full code to be able to meaningfully help you.

@Seventh7th-Son
Copy link
Author

Seventh7th-Son commented Jul 28, 2020

It is in a custom node program based on: litegraph.js library (c) Javi Agenjo http://tamats.com
https://github.com/jagenjo/litegraph.js
Below is the function that calls RGBquant for standard or dithered output. Data is an ImageData in Uint8ClampedArray format.

WidgetImage.prototype.RGBFilters = function(data, wid) {
    var opts = {
        colors: 256, // desired palette size
        method: 2, // histogram method, 2: min-population threshold within subregions; 1: global top-population
        boxSize: [64, 64], // subregion dims (if method = 2)
        boxPxls: 2, // min-population threshold (if method = 2)
        initColors: 4096, // # of top-occurring colors  to start with (if method = 1)
        minHueCols: 256, // # of colors per hue group to evaluate regardless of counts, to retain low-count hues
        dithKern: null, // dithering kernel name, see available kernels in docs below
        dithDelta: 0, // dithering threshhold (0-1) e.g: 0.05 will not dither colors with <= 5% difference
        dithSerp: false, // enable serpentine pattern dithering
        palette: [], // a predefined palette to start with in r,g,b tuple format: [[r,g,b],[r,g,b]...]
        reIndex: false, // affects predefined palettes only. if true, allows compacting of sparsed palette once target palette size is reached. also enables palette sorting.
        useCache: true, // enables caching for perf usually, but can reduce perf in some cases, like pre-def palettes
        cacheFreq: 10, // min color occurance count needed to qualify for caching
        colorDist: "euclidean", // method used to determine color distance, can also be "manhattan"
    };

    // RgbQuant options with defaults (not required)

    if (this.properties.Dither_Opts[0] != 'Off') {
        var Dither_Opts = this.properties.Dither_Opts[0];

        if (this.properties.Dither_Serp[0] == "true") {
            Dither_Serp = true;
        } else {
            Dither_Serp = false;
        }

        var Dither_Delta = parseFloat(this.properties.Dither_Delta[0]);
        var DitherColors = parseInt(this.properties.DitherColors[0]);

        var opts1 = {
            colors: DitherColors, // desired palette size
            reIndex: true,
            dithKern: Dither_Opts,
            dithSerp: Dither_Serp,
            dithDelta: Dither_Delta,
            useCache: false,
            minHueCols: 256
        }
        var q = new RgbQuant(opts1);
        q.sample(data, wid);
        var pal = q.palette(true);
        data = q.reduce(data); //pixels

        return data;
    }

    var q = new RgbQuant(opts);
    q.colors = parseInt(this.properties.Colors[0]);
    q.sample(data, wid);
    var pal = q.palette(true);
    data = q.reduce(data); //pixels

    return data;
};

@leeoniya
Copy link
Owner

i'm sorry, this is not enough for me to say anything.

if i have no way of running the code on my machine, then i have no way to answer questions. i have no idea what this.properties.Dither_Opts[0] contains, i have no idea what your data looks like. i have no idea if you're running in Node or in a Browser or which browser, etc, etc.

please make something that i can run on my machine which shows your issue. for example: https://jsfiddle.net/wtyxjzs5/

@Seventh7th-Son
Copy link
Author

Dither_Opts[0] is just an array of all the dithering types like 'FloydSteinberg' etc. This software is very very custom to one application. I will try to make a jsfiddle example. It will be a while I fiddle around learning jsfiddle. Thank you. I will close this it for now and keep tabs on any updates.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants