andybons / gogif

The (no longer) missing GIF encoder for #golang
BSD 2-Clause "Simplified" License
23 stars 6 forks source link

MedianCutQuantizer: No transparency support; no way to use just the palette calculation #4

Open ivucica opened 2 years ago

ivucica commented 2 years ago

As far as I could read, the MedianCutQuantizer's generated palette does not have space for a transparent color.

Given non-paletted img, this is what I do -- tell the quantizer to generate a paletted image, then prepend it with transparent color (I like having transparency as the zeroth color in the palette).

It makes me uneasy that dst.Set() is not skippable, given I have no use for the actual pixels, but I've chosen that's still fine as I still get a palette back:

quantizer := gogif.MedianCutQuantizer{NumColor: 255} // Up to 255 colors plus 1 space for transparency.

pal := image.NewPaletted(img.Bounds(), nil)
quantizer.Quantize(pal, img.Bounds(), img, image.ZP)

// Create a version of paletted image with color.Transparent in it. That's the first
// color so the empty image defaults to it.
palTransparent := image.NewPaletted(img.Bounds(), append(color.Palette([]color.Color{color.Transparent}), pal.Palette...))

// Now use draw.Draw() to create a version of the image which has the
// MedianCutQuantizer's palette plus transparent color.
draw.Draw(palTransparent, img.Bounds(), img, image.ZP, draw.Over)

g.Image = append(g.Image, palTransparent)                                                                                                                                                                                                                   
g.Delay = append(g.Delay, 50)                                                                                                                                                                                                                               
g.Disposal = append(g.Disposal, gif.DisposalBackground)                                                                                                                                                                                                     
g.BackgroundIndex = 0 // image.Transparent                                                                                                                                                                                                                  

draw.Draw is from image/draw, naturally. g is an image/gif.GIF.