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

setTransparent #3

Open
forresto opened this issue Jan 12, 2012 · 15 comments
Open

setTransparent #3

forresto opened this issue Jan 12, 2012 · 15 comments

Comments

@forresto
Copy link
Contributor

Have you gotten setTransparent(Number color) to work?

@forresto
Copy link
Contributor Author

Like... what kind of number is it expecting for the color? I'm passing 0xFFFFFF but white isn't transparent... sometimes a random other color is but I can't figure it out.

@forresto
Copy link
Contributor Author

Anybody want to hack on https://wiki.mozilla.org/APNG_Specification encoding with me?

@forresto
Copy link
Contributor Author

Here is one of the rare frames where transparency (0x00FF00) worked:

transparency worked

Most of the time it doesn't:

transparency didn't work

@forresto
Copy link
Contributor Author

This might be a bug: GIFEncoder.js#L351

        for (var i/*int*/ = 0; i < len;) {
          var dr/*int*/ = r - (colorTab[i++] & 0xff);
          var dg/*int*/ = g - (colorTab[i++] & 0xff);
          var db/*int*/ = b - (colorTab[i] & 0xff);
          var d/*int*/ = dr * dr + dg * dg + db * db;
          var index/*int*/ = i / 3;
          if (usedEntry[index] && (d < dmin)) {
            dmin = d;
            minpos = index;
          }
          i++;
        }

That var index/*int*/ = i / 3; will be 2/3 the first time. I changed the block to:

        for (var i/*int*/ = 0; i < len;) {
          var dr/*int*/ = r - (colorTab[i++] & 0xff);
          var dg/*int*/ = g - (colorTab[i++] & 0xff);
          var db/*int*/ = b - (colorTab[i++] & 0xff);
          var d/*int*/ = dr * dr + dg * dg + db * db;
          var index/*int*/ = (i / 3) - 1;
          if (usedEntry[index] && (d < dmin)) {
            dmin = d;
            minpos = index;
          }
        }

With this I'm getting better, but still random results:

better, but still random results

@forresto
Copy link
Contributor Author

Testing it today... colors were crap at 200x200 and fine at 300x300... maybe has something to do with this. Will look more.

@g-regor
Copy link

g-regor commented Dec 23, 2012

The quantization algorithm puts multiple entries into the color table for the same color, so then there are different indices for the same color. Because of that, color that should be transparent, has different index than the transparency index.

I wrote a fix, that sets all the pixel indices, that should be transparent to transparency index.
GIFEncoder.js#L337

if (transparent != null) {
    transIndex = findClosest(transparent);

    var r = colorTab[transIndex*3];
    var g = colorTab[transIndex*3+1];
    var b = colorTab[transIndex*3+2];
    var trans_indices = [];
    for (var i=0; i<colorTab.length; i+=3)
    {
        var index = i / 3;
        if (!usedEntry[index]) continue;
        if (colorTab[i] == r && colorTab[i+1] == g && colorTab[i+2] == b)
            trans_indices.push(index);
    }
    for (var i=0; i<indexedPixels.length; i++)
        if (trans_indices.indexOf(indexedPixels[i]) >= 0)
            indexedPixels[i] = transIndex;
}

@Pl4n3
Copy link

Pl4n3 commented Jan 13, 2013

Also, to run, line 363 must use floor function here:

var index/int/ = Math.floor(i / 3);

@forresto
Copy link
Contributor Author

Thanks @grego87, transparent works now:

trans

There is still a huge difference in the color quality at 200x200 vs 300x300... any leads on that bug?
200x200 vs 300x300
(here is the meemoo app that I used to make this test)

@antimatter15
Copy link
Owner

Have you tried out https://github.com/deanm/omggif

@forresto
Copy link
Contributor Author

It does look a little cleaner but you have to manually set the palette... I might port that part of yours to work with his...

@raducostea
Copy link

Hi,

Any idea when the quality depending on the canvas size may get fixed?

@forresto
Copy link
Contributor Author

forresto commented May 4, 2013

I'm pretty sure the size/color bug #6 is in NeuQuant.js, because I got it working with OMGGIF and they bug is still there. I'm going to start a bounty on Stack Overflow.

@forresto
Copy link
Contributor Author

@raducostea This patch should fix the color/size issue: https://github.com/antimatter15/jsgif/pull/8/files

@memalign
Copy link

memalign commented Jan 2, 2022

Note that there are TWO places that need to be changed from:
var index = i / 3;
To
var index = Math.floor(i / 3);

  • In the code g-regor posted above
  • In the implementation of findClosest

Without these two fixes the wrong color is chosen as the transparency color.

(I discovered this when debugging why 0x000000 worked as a transparency color but 0xFFFFFF did not)

flyskywhy added a commit to flyskywhy/react-native-gifencoder that referenced this issue Jan 16, 2023
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

7 participants