Open forresto opened 12 years ago
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.
Anybody want to hack on https://wiki.mozilla.org/APNG_Specification encoding with me?
Here is one of the rare frames where transparency (0x00FF00) worked:
Most of the time it doesn't:
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:
Testing it today... colors were crap at 200x200 and fine at 300x300... maybe has something to do with this. Will look more.
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;
}
Also, to run, line 363 must use floor function here:
var index/int/ = Math.floor(i / 3);
Thanks @grego87, transparent works now:
There is still a huge difference in the color quality at 200x200 vs 300x300... any leads on that bug? vs (here is the meemoo app that I used to make this test)
Have you tried out https://github.com/deanm/omggif
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...
Hi,
Any idea when the quality depending on the canvas size may get fixed?
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.
@raducostea This patch should fix the color/size issue: https://github.com/antimatter15/jsgif/pull/8/files
Note that there are TWO places that need to be changed from: var index = i / 3; To var index = Math.floor(i / 3);
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)
You can try gifenc
Because my react-native-gifencoder is also some fork of gif.js
But in my react-native-runescape-text I replace react-native-gifencoder
with gifenc
for Fix when one color e.g. '#ff0000' only have 1 or 2 or 3 pixel in one frame, the generated gif pixel will be '#9f0000'; fix some frame not transparent but black; reduce gif size 10x
Have you gotten
setTransparent(Number color)
to work?